0

I have written a function that makes an HTTP request and the response stores in a Bundle to subsequently initialize an activity.

public static void communicate(final Context context, String url, final String typeResponse, final Intent intent) {
    RequestQueue queue = Volley.newRequestQueue(context);

    RequestFuture<String> future = RequestFuture.newFuture();
    StringRequest stringRequest = new StringRequest(Request.Method.POST, BASE_URL + url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            //Toast.makeText(context, response, Toast.LENGTH_SHORT).show();
            Bundle bundle = new Bundle();
            switch (typeResponse) {
                case "text":
                    bundle.putString("response", response);
                    break;
                case "json":
                    try {
                        JSONObject jsonObject = new JSONObject(response);
                        JSONArray names = jsonObject.names();
                        for (int i = 0; i < names.length(); i++) {
                            //Toast.makeText(context, names.getString(i), Toast.LENGTH_SHORT).show();
                            bundle.putString(names.getString(i), jsonObject.getString(names.getString(i)));
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    break;
            }

            intent.putExtras(bundle);
            context.startActivity(intent);
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Toast.makeText(context, "error", Toast.LENGTH_SHORT).show();
        }
    }) {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<String, String>();
            params.put("test", "hi!!");
            return params;
        }
    };
    queue.add(stringRequest);
}

But I want return the Bundle object for use that function like this:

Bundle myBundle = communicate('httl://qwe.asd', 'json')

How can I to modifier my function?

Thanks.

Pols63
  • 25
  • 1
  • 7
  • in order to do so, you have to change your async volley request to synchronous – Qasim Aug 24 '18 at 16:55
  • You can use Rx PublishSubject bundleSubject = PublishSubject.create(); ... @Override public void onResponse(String response) { Bundle bundle = new Bundle(); ... bundleSubject.accept(bundle); } //Elsewhere in the code bundleSubject .observeOn(AndroidSchedulers.mainThread()) .subscribe(bundle -> { Intent intent = new Intent(getContext(), OtherActivity.class); intent.putExtras(bundle); getContext().startActivity(intent); }); – Zachary Sweigart Aug 24 '18 at 17:27

1 Answers1

0

Volley request are asynchronous, so i recommend you put inner your onResponse other function to be process your bundle. As well, you can create an interface to send your response in other place. Something like this

interface

 public interface onResponseCallback {
  void onResponse(Bundle bundle);
}

activity

      public MyActivity extends AppCompatActivity implements onResponseCallback{


        public void onCreate(Bundle....){
    MyRequest myrequest = new MyRequest(this);
        ..}

        public void onResponse(Bundle bundle){
        //bundle argument is your response from request,
        // do some with your response
Intent intent = new Intent....
intent.putExtras(bundle);
            startActivity(intent);
        }


        }

Request class

public class MyRequest{

OnResponseCallback onResponseCallback= null;

public MyRequest(onResponseCallback onResponseCallback)
this.onResponseCallback = onResponseCallback;
}

public void communicate(final Context context, String url, final String typeResponse, final Intent intent) {
    RequestQueue queue = Volley.newRequestQueue(context);

    RequestFuture<String> future = RequestFuture.newFuture();
    StringRequest stringRequest = new StringRequest(Request.Method.POST, BASE_URL + url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            //Toast.makeText(context, response, Toast.LENGTH_SHORT).show();
            Bundle bundle = new Bundle();
            switch (typeResponse) {
                case "text":
                    bundle.putString("response", response);
                    break;
                case "json":
                    try {
                        JSONObject jsonObject = new JSONObject(response);
                        JSONArray names = jsonObject.names();
                        for (int i = 0; i < names.length(); i++) {
                            //Toast.makeText(context, names.getString(i), Toast.LENGTH_SHORT).show();
                            bundle.putString(names.getString(i), jsonObject.getString(names.getString(i)));
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    break;
            }
             onResponseCallback.onResponse(bundle);   
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Toast.makeText(context, "error", Toast.LENGTH_SHORT).show();
        }
    }) {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<String, String>();
            params.put("test", "hi!!");
            return params;
        }
    };
    queue.add(stringRequest);
}

}

and if you dont like nothing of this, maybe you can use constants or put in sharedpreferences to save your bundle object.

I hope that helps you.

Daniel Carreto
  • 211
  • 1
  • 9
  • 1
    Thanks. But I don't want to launch an activity. I only want to capture the data. What synchronous alternative there is? – Pols63 Aug 24 '18 at 17:43
  • Oh i´m sorry, i just copy from your code. you don´t have any options, only the interface or create a method after onresponse callback are your better options, just change the code in response (only its demostrative). You need to wait that request response to continue with your flow, the request needs to be asynchronous to avoid stop the main thread. – Daniel Carreto Aug 24 '18 at 18:00