从另一个的AsyncTask的onPostExecute推出的AsyncTask的不API 10正确执行 [英] An asyncTask launched from an onPostExecute of another AsyncTask does not execute properly in API 10

查看:210
本文介绍了从另一个的AsyncTask的onPostExecute推出的AsyncTask的不API 10正确执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

设置:

我有了一个名为方法的单应用程序类 fetchUpdates()。这种方法是由 UpdaterService (一IntentService)类调用。 fetchUpdates()方法仅调用DownloadDataAsyncTask然后调用 UpdateDbAsyncTask onPostExecute 如果数据已成功下载。无论AsyncTasks驻留在应用程序类(不知道这是初步认识到这个问题)。

I have a singleton application class that has a method named fetchUpdates(). This method is called by an UpdaterService (an IntentService) class. fetchUpdates() method simply calls DownloadDataAsyncTask which then calls UpdateDbAsyncTask during onPostExecute if the data were successfully downloaded. Both AsyncTasks reside in the application class (not sure if this is relavant to the problem).

public synchronized void fetchUpdates() {
    String[] mURLs = getURLs();
    new DownloadDataAsyncTask().execute(mURLs[0], mURLs[1]);
}

DownloadDataAsyncTask类

DownloadDataAsyncTask class

private class DownloadDataAsyncTask extends AsyncTask<String, Void, JSONObject[]> {

    @Override
    protected synchronized JSONObject[] doInBackground(String... params) {
        String urlData = (String) params[0];
        String urlId = (String) params[1];
        JSONObject[] jSON = new JSONObject[] {
                JSONfunctions.getJSONfromURL(urlData),
                JSONfunctions.getJSONfromURL(urlId) };
        return mJSON;
    }

    @Override
    protected void onPostExecute(JSONObject[] result) {
         if (result[0] != null && result[1] != null) {
             new UpdateDbAsyncTask().execute(result[0], result[1]);
         } else {
             displayFailureToast();
         }
    }
}

UpdateDbAsyncTask类

UpdateDbAsyncTask class

private class UpdateDbAsyncTask extends AsyncTask<JSONObject, Void, int[]> {

    @Override
    protected synchronized int[] doInBackground(JSONObject... params) {
        Log.d(TAG, "UpdateDbAsyncTask doInBackground BEGIN");
        int[] info = updateDb(params[0], params[1]);
        Log.d(TAG, "UpdateDbAsyncTask doInBackground RETURNING RESULT");
        return info
    }

    @Override
    protected void onPostExecute(int[] result) {
        Log.d(TAG, "UpdateDbAsyncTask onPostExecute BEGIN");
        if (result[0] > 0) makeNotification(0);
        if (result[1] > 0) makeNotification(1);
    }
}

问题:

一切正常,在16 API罚款,但在API 10. doInBackground后 UpdateDbAsyncTask 的执行将暂停onCancelled(Object)方法也不会被调用。

Everything works fine in API 16, but execution of UpdateDbAsyncTask halts after the doInBackground in API 10. The onCancelled(Object) method is not called either.

logcat的输出

06-22 16:11:51.047: D/dalvikvm(499): VFY: replacing opcode 0x6e at 0x0089
06-22 16:11:51.057: D/dalvikvm(499): VFY: dead code 0x008c-008e in Lcom/daybreak/android/test/MyApplication$UpdateDbAsyncTask;.onPostExecute ([I)V
06-22 16:11:51.087: D/MyApplication(499): UpdateDbAsyncTask doInBackground BEGIN
06-22 16:11:51.187: D/MyApplication(499): UpdateDbAsyncTask doInBackground RETURNING RESULT
06-22 16:11:51.197: W/MessageQueue(499): Handler{40567510} sending message to a Handler on a dead thread
06-22 16:11:51.197: W/MessageQueue(499): java.lang.RuntimeException: Handler{40567510} sending message to a Handler on a dead thread
06-22 16:11:51.197: W/MessageQueue(499):    at android.os.MessageQueue.enqueueMessage(MessageQueue.java:196)
06-22 16:11:51.197: W/MessageQueue(499):    at android.os.Handler.sendMessageAtTime(Handler.java:457)
06-22 16:11:51.197: W/MessageQueue(499):    at android.os.Handler.sendMessageDelayed(Handler.java:430)
06-22 16:11:51.197: W/MessageQueue(499):    at android.os.Handler.sendMessage(Handler.java:367)
06-22 16:11:51.197: W/MessageQueue(499):    at android.os.Message.sendToTarget(Message.java:349)
06-22 16:11:51.197: W/MessageQueue(499):    at android.os.AsyncTask$3.done(AsyncTask.java:214)
06-22 16:11:51.197: W/MessageQueue(499):    at java.util.concurrent.FutureTask$Sync.innerSet(FutureTask.java:253)
06-22 16:11:51.197: W/MessageQueue(499):    at java.util.concurrent.FutureTask.set(FutureTask.java:113)
06-22 16:11:51.197: W/MessageQueue(499):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:311)
06-22 16:11:51.197: W/MessageQueue(499):    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
06-22 16:11:51.197: W/MessageQueue(499):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
06-22 16:11:51.197: W/MessageQueue(499):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
06-22 16:11:51.197: W/MessageQueue(499):    at java.lang.Thread.run(Thread.java:1019)
06-22 16:11:55.717: W/GAV2(499): Thread[Service Reconnect,5,main]: Service unavailable (code=1), using local store.

进一步研究

借助线程规则了解AsyncTask的状态:

The threading rules for AsyncTask state that:


  • 的AsyncTask的类必须在UI线程上加载。这是作为JELLY_BEAN的自动完成。

  • 任务实例必须在UI线程上创建。

  • 执行(参数...)必须在UI线程调用。

  • 等...

要我的理解(这并不多,刚开始编程)的第一个 UpdateDbAsyncTask 完全是在这两个API,因为它没有违反任何规则的线程执行。但是,第二个是不是违反的线程规则之一,使其doInBackground后停止执行,或者是别的东西完全超出了我的理解。

To my understanding (which is not much, just started programming) the first UpdateDbAsyncTask is executed completely in both APIs because it does not violate any of the threading rules. But the second one is either violating one of the threading rules, causing it to halt execution after doInBackground, or it is something else completely beyond my understanding.

我还发现别人有类似<​​一个href=\"http://stackoverflow.com/questions/13898210/asynctask-onpostexecute-is-not-called-on-2-3\">issue.后来又有人提出了问题。

I also found someone else with a similar issue. And later it was suggested in the question to

简单地使用AsyncTask的类API15 +在我的code在所有时间

simply using AsyncTask class for API15+ in my code at all times

不过我不太清楚怎么做,要么。

But I'm not quite sure how to do that either.

任何帮助将是非常美联社preciated。谢谢!

Any help would be much appreciated. Thanks!

更新1

问题只出现在我称之为 UpdaterService IntentService类(调用 fetchUpdates()中的方法应用程序类)的一个活动。在code,我在我的 MainActivity 下面是:

The problem only arises when I call the UpdaterService IntentService class (which calls the fetchUpdates() method in the Application class) from an Activity. The code I had in my MainActivity is below:

startService(new Intent(this, UpdaterService.class));

然而,当我叫 fetchUpdates()直接使用code

MyApplication myApp = (MyApplication) getApplication();
myApp.fetchUpdates();

MainActivity ,在API 10完美执行的一切。

from the MainActivity, everything is executed perfectly in API 10.

和也注意到, UpdaterService 使用的设置定期叫做广播接收器类也调用使用重复报警。在这种情况下,AsyncTasks执行如预期......很奇怪的。

And also note that the UpdaterService is also invoked using a BroadcastReceiver class which is set be called at regular intervals using a repeating alarm. In this case the AsyncTasks are executed as expected... very strange.

更新2

街道波士顿似乎是正确的答案。但是,奇怪的是,以下似乎工作,以及:

The answer by Streets Of Boston seems to be the correct answer. But, curiously, the following seems to work as well:

runOnUiThread(new Runnable() {
    public void run() {
        Intent serviceIntent = new Intent();
        serviceIntent.setClass(getApplicationContext(), UpdaterService.class);
        startService(serviceIntent);
    }
});

我使用上述code键启动 IntentService MainActivity 而不是 startService(新意图(这一点,UpdaterService.class)); ,似乎问题并没有持续下去。

I used the above code to start the IntentService from the MainActivity instead of startService(new Intent(this, UpdaterService.class)); and the problem does not seem to persist.

推荐答案

首先,code在一个IntentService执行已经运行在后台线程。没有必要使用的AsyncTask。

First of all, the execution of code in an IntentService already runs in a background thread. There is no need to use AsyncTask.

我并不感到惊讶,你得到这个错误。我很惊讶,你的第二个AsyncTask的被调用的。当你的IntentService完成调用fetchUpdates方法,服务等做你的进程和/或线程可以安排被摧毁/杀死。根据不同的操作系统如何咄咄逼人的是,这可能会立即或分钟后发生。这意味着你的code得到要对死线程上运行,这是发生了什么。

I'm not surprised you get this error. I'm surprised that your second AsyncTask gets called at all. When your IntentService finishes calling the fetchUpdates method, your service is done and your process and/or threads could be scheduled to be destroyed/killed. Depending on how aggressive the OS is, this may happen immediately or minutes later. This means that your code gets to be run on a dead thread, and that's what happens.

解决方案:
不要从内部IntentService使用AsyncTasks。相反,只要直接调用那些AsyncTasks的code在IntentService。

Solution: Don't use AsyncTasks from within IntentService. Instead, just call the code from those AsyncTasks in your IntentService directly.

这篇关于从另一个的AsyncTask的onPostExecute推出的AsyncTask的不API 10正确执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆