Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making HTTP request using OkHttp library inside doInBackground() of AsyncTask blocks UI operation

Tags:

android

okhttp

I was trying making OkHttp request in AsyncTask using call.execute() -- Synchronous call.

I have two buttons in my layout. Pressing button1 starts AsyncTask, that executes OkHttp request.call.execute().

And pressing button2, I just update a TextView.

Observation: While AsyncTask is running, I can not update TextView.

But, if I don't use AsyncTask and use OkHttpClient.newCall().enqueue() method,then I can update TextView by pressing button2.

Any answer for "Why using AsyncTask in this case not working"?

Source Code Sample:

bpost = (Button) findViewById(R.id.bpost);
    bpost.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            i++;
            tv.setText(""+i);
        }
    });


bstart.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

        OkHttpHandler handler = new OkHttpHandler();

            byte[] image = new byte[0];
            try {
                image = handler.execute(url).get();
                if (image != null && image.length > 0) {
                    Bitmap bitmap = BitmapFactory.decodeByteArray(image, 0, image.length);
                    imageView.setImageBitmap(bitmap);
                    tv.setText("Total btytes download: " + image.length);
                }
            } catch (Exception e) {
                tv.setText("sorry, something went wrong!");
            }
        }


public class OkHttpHandler extends AsyncTask<String, Void, byte[]> {

    OkHttpClient client = new OkHttpClient();

    @Override
    protected byte[] doInBackground(String... params) {

        Request.Builder builder = new Request.Builder();
        builder.url(params[0]);
        Request request = builder.build();



        try {
            Response response = client.newCall(request).execute();
            return response.body().bytes();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
like image 707
Anish Mittal Avatar asked Jul 06 '16 06:07

Anish Mittal


People also ask

Which method is called by the doInBackground () to publish updates on the user interface thread?

protected final void publishProgress (Progress... This method can be invoked from doInBackground(Params...) to publish updates on the UI thread while the background computation is still running. Each call to this method will trigger the execution of onProgressUpdate(Progress...) on the UI thread.

What is OkHttp library in Android?

OkHttp is a third-party library developed by Square for sending and receive HTTP-based network requests. It is built on top of the Okio library, which tries to be more efficient about reading and writing data than the standard Java I/O libraries by creating a shared memory pool.

What is the use of OkHttp?

OkHttp is an HTTP client from Square for Java and Android applications. It's designed to load resources faster and save bandwidth. OkHttp is widely used in open-source projects and is the backbone of libraries like Retrofit, Picasso, and many others.

What method must be overridden when using AsyncTask to execute statements on a separate thread?

In Android, AsyncTask (Asynchronous Task) allows us to run the instruction in the background and then synchronize again with our main thread. This class will override at least one method i.e doInBackground(Params) and most often will override second method onPostExecute(Result).


1 Answers

This is because get() method of AsyncTask waits for the computation to finish in doInBackground method and then retrieves its result. See this link.

This will make your main UIThread in wait mode until doInBackground finish its execution or there is some exception occur(i.e. CancellationException,ExecutionException and InterruptedException).

You should use onPostExecute(Result) override method of AsyncTask.

private class OkHttpHandler extends AsyncTask<String, Void, byte[]> {

        OkHttpClient client = new OkHttpClient();

        @Override
        protected byte[] doInBackground(String... params) {

            Request.Builder builder = new Request.Builder();
            builder.url(params[0]);
            Request request = builder.build();
            try {
                Response response = client.newCall(request).execute();
                return response.body().bytes();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(byte[] bytes) {
            super.onPostExecute(bytes);
            try {
                if (bytes != null && bytes.length > 0) {
                    Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                    imageView.setImageBitmap(bitmap);
                    tv.setText("Total btytes download: " + bytes.length);
                }
            } catch (Exception e) {
                tv.setText("sorry, something went wrong!");
            }
        }
    }
like image 58
Pravin Divraniya Avatar answered Nov 12 '22 05:11

Pravin Divraniya