Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Application hangs and suspends all threads while using AsyncTask

I am trying to use the AsyncTask class to get a website's content. The logcat tells me W/art: Suspending all threads took: 15(or any other number)ms repeatedly. My application is frozen until the log messages are done printing. UI shows up after the log is done. I followed a tutorial and have double checked that my code should be the same as the tutorial. After a while, it logs a few lines of code from the website, but nothing more. I tried with different websites as well. Here is my AsyncTask:

public class MainActivity extends AppCompatActivity {

    public class DownloadTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... urls) {

            String result = "";
            URL url;
            HttpURLConnection urlConnection = null;

            try {

                url = new URL(urls[0]);

                urlConnection = (HttpURLConnection) url.openConnection();

                InputStream in = urlConnection.getInputStream();

                InputStreamReader reader = new InputStreamReader(in);

                int data = reader.read();

                while (data != -1) {

                    char current = (char) data;

                    result += current;

                    data = reader.read();

                }

                return result;

            } catch (Exception e) {

                e.printStackTrace();

            }

            return null;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DownloadTask task = new DownloadTask();
        String result = null;

        try {

            result = task.execute("http://www.vg.no/").get();

            Log.i("URL content" , result);

        } catch (InterruptedException e) {

            e.printStackTrace();

        } catch (ExecutionException e) {

            e.printStackTrace();

        }

    }


}
like image 796
Emil Øgård Avatar asked Oct 13 '15 23:10

Emil Øgård


3 Answers

The following line is a problem:

result = task.execute("http://www.vg.no/").get();

The .get() part of this statement means "wait until the task completes". This effectively blocks the UI thread while the task executes.

Just let the background task do its stuff and get any results back via onPostExecute(). Check out the following AsyncTask:

public class MainActivity extends AppCompatActivity {

   public class DownloadTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... urls) {
            ...
        }

        @Override
        protected void onPostExecute(String result) {
            Log.i("URL content" , result);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DownloadTask task = new DownloadTask();
        task.execute("http://www.vg.no/");
    }


}
like image 71
adelphus Avatar answered Oct 13 '22 20:10

adelphus


First of all I think you misused AsyncTask. AsyncTask should be used asynchronously not synchronously using get().

you should add onPostExecute inside your AsyncTask and get the result there.

protected void onPostExecute(String result) {
     //You could get the result here
}

You could read better tutorial here -> http://developer.android.com/reference/android/os/AsyncTask.html

like image 26
Niko Adrianus Yuwono Avatar answered Oct 13 '22 18:10

Niko Adrianus Yuwono


I am trying to use the AsyncTask class to get a website's content. The logcat tells me W/art: Suspending all threads took: 15(or any other number)ms repeatedly.

You have better alternative to AsyncTask.

From "Threading Performance" article by developer.android.com:

When using AsyncTask, there are a few important performance aspects to keep in mind. First, by default, an app pushes all of the AsyncTask objects it creates into a single thread. Therefore, they execute in serial fashion, and—as with the main thread—an especially long work packet can block the queue. For this reason, we suggest that you only use AsyncTask to handle work items shorter than 5ms in duration.

You can use HandlerThread as an alternative. If you have many URLs to be fetched, go for ThreadPoolExecutor

Have a look at related post(s):

Handler vs AsyncTask vs Thread

like image 23
Ravindra babu Avatar answered Oct 13 '22 19:10

Ravindra babu