5

我正在尝试解决的应用程序出现非常零星的故障。在进入应用程序时,主 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 崩溃报告。该应用程序仍然处于活动状态(我可以导航到其他活动并返回),所以我不知道什么可能会阻止这个后台线程正常运行。有任何想法吗?

4

1 回答 1

2

遗憾AsyncTask的是,它不适合关键代码执行,因为根据ThreadPool基本大小和最大大小,您的 AsyncTask 可能永远不会执行。

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

尽管我在 Android Camera App 中也看到过这样做,但阻止 UI 线程等待事件并不是一个好主意,因为您可能会收到 ANR(应用程序未运行)通知。

看看这个:AsyncTask 在概念上真的有缺陷还是我只是错过了什么?

考虑使用IntentServicesHandlerThread或者ThreadPoolExecutors如果您需要一种可能更好的方法来将您的工作线程与您的 UIThread 同步。

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

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

于 2013-07-13T00:12:38.717 回答