Recently again encountered AsyncTask bug, found this problem is still relatively common, and more implicit, in this record.

I wrote an app related to pictures before, and needed to crop the pictures. Naturally, I went to GitHub to find an open source library for cutting pictures.

I first used UCrop, but found that in my app, the picture could not be loaded after entering the picture clipping page, but it could be loaded normally after running demo. Then I switched to Android-image-Cropper, and found the same situation. I could not load images from clipping pages in my app, but the demo could work normally.

Then I checked the code in other places, and felt that there was no problem, which made me very confused. I looked at the issues of the two projects again, and found that some people raised the same problems as me, but the author could not reproduce, no one knows the reason. So you have to read the fucking souce code.

After a brief browse, both projects load images asynchronously using AsyncTask. Execute (Params… Params, the whole process seems to be fine. Finally I wondered if the AsyncTask bomb was wrong, but my own code didn’t use AsyncTask at all.

The known problem with AsyncTask is that it will execute each task linearly by default, that is, it will execute the next task only after the previous task is completed, and the later task will wait until the previous task is completed.

I thought about what I had done on the page before cropping the image, and found that I had requested to load a Facebook AD. Here I used the Facebook AD SDK, and I didn’t know the source of the SDK. Then I loaded the AD and removed it, and the image cropping was normal. It turned out to be the facebook AD SDK, because I did not climb the wall to access Facebook naturally slow, the AD SDK must be using AsyncTask to execute network requests, resulting in a block.

While there are many alternatives to AsyncTask, it is still used in some situations. For example, with the Facebook AD SDK, MY guess is that they used AsyncTask because they wanted to keep the SDK as small as possible, and if they relied on other third party things for web requests then the SDK ended up being too big, so they only used the system classes. Both picture clipping libraries use AsyncTask for the same reason.

So we still need to understand the use of AsyncTask, don’t be fooled by it.

Follow the description in the AsyncTask official documentation

AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent package such as Executor, ThreadPoolExecutor and FutureTask.

AsyncTask is only suitable for short, time-consuming operations of a few seconds at most. Execute AsyncTask (Params… SERIAL_EXECUTOR, which uses the asynctask. SERIAL_EXECUTOR thread pool to execute the next task after the previous task has completed. Do not use execute() for some IO time-consuming operations.

If you must perform some time-consuming operation, you can call executeOnExecutor(Executor exec, Params… Params), passing in a custom thread pool. Self-query data unfamiliar with thread pool concepts. AsyncTask also has a static constant THREAD_POOL_EXECUTOR. This is a predefined thread pool whose core threads are the number of cpus plus 1 and the maximum number of threads is twice the number of cpus plus 1. However, once the number of tasks has exceeded the maximum number of threads, subsequent tasks will have to wait for the previous task to complete, and you will need to create a new ThreadPoolExecutor to control the parameters. Or call the Executors. NewCachedThreadPool () to create a zero core number of threads, no maximum limit the thread pool thread. I suggest you can simply look at AysncTask source code.

In Android-image-Cropper, Issues 183, I proposed to the author to use a custom thread pool to execute AsyncTask. He said that according to the official AsyncTask document, I should not place long time work in AsyncTask elsewhere. However, I have never used AsyncTask myself, because I was cheated by The Facebook advertising SDK. I could not change the source code of the SDK, so I had to ask him to change the code of the tailored library. In the future, we will not be able to do our own standards, but also to guard against being cheated by others’ libraries, especially large projects with too many dependencies.

There are also some caveats to thread pool usage, which can cause memory overruns if abused, but I’ll cover them in another article.

The resources

  1. AsyncTask
  2. StackOverflow: Android SDK AsyncTask doInBackground not running
  3. A handler that is not called by doInBackground occurs when AsyncTask is used
  4. Why is the doInBackground method executed so long after AsyncTask calls the execute method?
  5. Github: UCrop, issue 141
  6. Github: Android-Image-Cropper, issues 183