Emil Øgård
Emil Øgård

Reputation: 1029

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();

        }

    }


}

Upvotes: 8

Views: 26546

Answers (4)

Ravindra babu
Ravindra babu

Reputation: 38950

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

Upvotes: 2

adelphus
adelphus

Reputation: 10316

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/");
    }


}

Upvotes: 15

Halit Onur Karabaş
Halit Onur Karabaş

Reputation: 1

I got the same problem in such a way. "while" is the reason of your problem, you need to get rid of it.

Upvotes: -4

Niko Adrianus Yuwono
Niko Adrianus Yuwono

Reputation: 11122

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

Upvotes: 2

Related Questions