是什么导致AsyncTask无法执行?

时间:2013-02-24 22:08:40

标签: android android-asynctask

我的应用程序中有一个非常零星的失败,我试图解决。在进入应用程序时,主UI线程处理结束并将控制权传递给后台线程以检索某些数据。检索数据时,控件会传回主UI线程进行处理以进行显示。然而,在一些罕见的场合(它在99%的时间内工作),AsyncTask似乎无法被调用,使应用程序处于一个不稳定的静态状态,永远等待AsyncTask完成。

以下是Activity

中代码的快照
//method call from main UI thread
private void fetchSomeData() {
    Log.d("myTag", "In fecthSomeData()");
    new ReadFileAsyncTask<DataModel>().execute(this);
}

这是ReadFileAsyncTask实施:

public class ReadFileAsyncTask<A> extends AsyncTask<I_ReadFileListener<A>, Void, A>
{
I_ReadFileListener<A> listener;

@Override
@SuppressWarnings("unchecked")
protected A doInBackground(I_ReadFileListener<A>... params)
{
    listener = params[0];
    Log.d("mytag", "BACKGROUND: Loading " + listener.getFilename() + " from disk");
    A fileContents = (A) FileUtils.readDataFromInternalStorage(listener.getContext(), listener.getFilename());
    return fileContents;
}

@Override
protected void onPostExecute(A result)
{
    Log.d("myTag", "FOREGROUND: Executing onFileRetrieved listener");
    listener.onFileRetrieved(result);
}
}

捕获这个罕见故障的日志:

In fetchSomeData()
...
(Other log messages from other interactions with the activity such as menu creation and navigation initialization)

但是,至关重要的是,不是doInBackground方法中第二行代码的日志语句。我有一个想法是这个日志声明失败了,但我没有看到任何强制停止消息,我的日志或ACRA崩溃报告中的错误。应用程序仍处于活动状态(我可以导航到其他活动并返回),因此我不知道可能会阻止此后台线程正常运行。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

可悲的是,AsyncTask不适用于关键代码执行,因为根据ThreadPool基数和最大大小,您的AsyncTask可能永远不会执行。

此外,onPostExecute方法可以在其引用的Activity(即其创建上下文)已被销毁时调用。您无法与它同步,而是可能在UI线程的AsyncThread上使用join()。

即使我在Android相机应用程序中也看到这样做,但是阻止等待事件的UI线程并不是一个好主意,因为你可以获得ANR(应用程序未运行)通知。

看看这个:Is AsyncTask really conceptually flawed or am I just missing something?

如果您需要一种更好的方法来将您的工作线程与您的UIThread同步,请考虑使用IntentServicesHandlerThreadThreadPoolExecutors

来自http://developer.android.com/training/run-background-service/create-service.html

  

此外,IntentService不受大多数​​用户界面生命周期事件的影响,因此它会在关闭AsyncTask的情况下继续运行