In android there is a need to perform any interactions with the “Internet” in another stream, but sometimes there is a need to wait for the result from the server and then do something with it and of course I would like not to barter any extra crutches in the main code to interact with components. A little thought decided to do something like this:

private void initRequest(){ final Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { Toast.makeText(MainActivity.this, (String) msg.obj, Toast.LENGTH_LONG).show(); }; }; Thread thread = new Thread(new Runnable() { @Override public void run() { Message message; if(Utils.isNetworkConnected(MainActivity.this)){ HttpClient httpclient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(INIT_HOST); httpGet.addHeader("Content-Type", "application/json"); try { HttpResponse httpResponse = httpclient.execute(httpGet); String strEntity = EntityUtils.toString(httpResponse.getEntity()); JSONObject jsonObject = new JSONObject(strEntity); Global_Variables.COORDS_INTERVAL = jsonObject.getInt(Constance.INIT_RECORD_INTERVAL); Global_Variables.POST_INTERVAL = jsonObject.getInt(Constance.INIT_SEND_INTERVAL); Global_Variables.TIME_CHECK_SPEED = jsonObject.getInt(Constance.INIT_SPEED_INTERVAL); Global_Variables.TRIGGER_SPEED = jsonObject.getInt(Constance.INIT_TRIGGER_SPEED); } catch (ClientProtocolException e) { message = new Message(); message.obj = "Failed send init request!"; handler.sendMessage(message); } catch (IOException e) { message = new Message(); message.obj = "Unsuccessful receiving entity!"; handler.sendMessage(message); } catch (JSONException e) { message = new Message(); message.obj = "Failed parse Json!"; handler.sendMessage(message); } }else{ message = new Message(); message.obj = "Check Internet connection!"; handler.sendMessage(message); } } }); thread.setName("Init request"); thread.start(); try { thread.join(); } catch (InterruptedException e) { throw new RuntimeException("Thread "+thread.getName()+" interrupted!"); } } 

For example, I took one of the functionals of my application. I don’t see any sense in the executed function itself, I would like to draw attention to such moments as: Handler (necessary for interacting with the UI thread), and the join () method for the thread that is needed to indicate the thread in which we started the thread thread , that it needs to wait for the thread to finish, this is necessary so that no one has time to use global data. What does all this give? And the fact that you quietly execute the method in another thread without unnecessary code in the main code and with all this the main thread is waiting for your completion, and as a result you can also interact with the UI stream. The only drawback of all this I see is that the result makes sense to send only at the end of the stream, for if it is done in the middle, then the code in the handler will not be executed due to join () until the entire thread does the work to the end. And now the question: what do you think about all this, did I come up with an interesting way or did I write some kind of nonsense?

  • How did AsyncTask not fit? - Suvitruf
  • 2
    There are already ready libraries for working with the network, for example, retrofit square.imtqy.com/retrofit, it encapsulates all the asynchronous logic, data parsing and offers convenient callbacks for ui notification, there is support for performing synchronous requests - nick_kryloff
  • @Suvitruf AsyncTask does the main thread really stop to wait for the main thread to complete? - BORSHEVIK
  • Stop the main thread can not be. This is very terrible. - Vladyslav Matviienko
  • @metalurgus you are probably right, during a long operation I can catch ANR - BORSHEVIK

2 answers 2

Good question, interesting solution. It was also always the most interesting who and how to cope with this task, in addition only sign for how I realize it. I have my CallBack class:

 public class CallBack<T> { public void onSuccess() { } public void onSuccess(T result) { } public void onFail(String message) { } public void onFailure(T result) { } } 

To work with API methods for GET and POST requests, I use the android-async-http library. In my opinion one of the best lib, which is constantly updated and developed. For example, there is a method to get a list of some objects:

 public static void getTestObjectsList(final String url, final Context context, final CallBack<ArrayList<TestObject>> callBack) { if (!Server.isOnline(context)) { callBack.onFail(context.getString(R.string.no_internet_error)); return; } Server.getAsyncHttpClient(context).get(url, new JsonHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, JSONArray jsonArray) { ArrayList<TestObject> testObjects = new ArrayList<>(); if (!(jsonArray.length() > 0)) { callBack.onSuccess(testObjects); return; } for (int i = 0; i < jsonArray.length(); i++) { try { JSONObject jsonObject = jsonArray.getJSONObject(i); TestObject testObject = new TestObject(); testObject.setId(jsonObject.getInt("id")); testObject.setTitle(jsonObject.getString("title")); testObject.setDescription(jsonObject.getString("description")); testObjects.add(testObject); } catch (JSONException e) { e.printStackTrace(); } } callBack.onSuccess(testObjects); } @Override public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) { callBack.onFail(errorResponse.getString("error")); } }); } 

Where Server.getAsyncHttpClient(context) returns new AsyncHttpClient() . All this stuff is done in a separate thread and in a separate class. I like to use this approach: if there is, for example, a TestObject object, then I describe all the operations that occur to it in the TestObjectManager class.

How I use it. For example, I call in my Activity request:

 TestObjectManager.getTestObjectsList(url, getApplicationContext(), new CallBack<ArrayList<TestObject>>() { @Override public void onSuccess(ArrayList<TestObject> testObjects) { //сюда приходит положительный результат. Здесь можно установить адаптер, скрыть прогресс бар и т.д. } @Override public void onFail(String error) { showShortMessage(error);//здесь просто показываем ошибку в случае неудачи } }); 

As we see, this code waits for the result from the execution of the request, and in any case will receive it, be it positive or negative. In general, I hope to share my experience in the case) And! waiting for constructive criticism)

  • Your decision is also quite interesting - BORSHEVIK
  • for all this, there is already a ready-made solution in retrofit or you can simply use OkHttp - nick_kryloff
  • @nick_kryloff But what is the fundamental difference between okhttp and asynchttp? - Android Android

It is impossible to block the main thred for more than 5 seconds, androyd will regard this as anr and crash the task