Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Asynctask在保留的工作程序片段中丢失引用,正在尝试循环Asynctask_Android_Multithreading_Android Fragments_Android Asynctask - Fatal编程技术网

Android Asynctask在保留的工作程序片段中丢失引用,正在尝试循环Asynctask

Android Asynctask在保留的工作程序片段中丢失引用,正在尝试循环Asynctask,android,multithreading,android-fragments,android-asynctask,Android,Multithreading,Android Fragments,Android Asynctask,我有一个应用程序,可以进行rest调用,并在GridView中表示数据 主要活动使用两个片段,一个UI片段和一个保留的工作者片段。worker片段包含一个执行REST调用的内部AsyncTask 一切都很好,我没有崩溃等,直到我尝试定期更新 为了执行间隔,我添加了一个处理程序。处理程序是工作程序片段的成员。在worker片段中,我有一个LoadAPI方法,该方法调用asynctask public void loadAPI(){ final String myURL = "http://

我有一个应用程序,可以进行rest调用,并在GridView中表示数据

主要活动使用两个片段,一个UI片段和一个保留的工作者片段。worker片段包含一个执行REST调用的内部AsyncTask

一切都很好,我没有崩溃等,直到我尝试定期更新

为了执行间隔,我添加了一个处理程序。处理程序是工作程序片段的成员。在worker片段中,我有一个LoadAPI方法,该方法调用asynctask

public void loadAPI(){
    final String myURL = "http://x.com/"
    handler.post(new Runnable() {
        public void run(){
            new APITask().execute(myURL);
            handler.postDelayed(this,10000);
        }
    });
}
问题是,当配置发生更改时,我的活动被销毁,并且onPostExecute在引用主活动侦听器时崩溃。但是我已经在我的worker片段中实现了onAttach。onCancel似乎是一个丑陋的选项,因为可以调用多个asynctasks,而我没有命名实例。我想我可以在worker片段中保留一个asynctasks列表,并在onestory中取消它们(丢失最新更新没关系),但我认为我在这里做错了什么。令人沮丧的是,在我进行连续轮询之前,worker frag和asynctask一直工作正常,我不明白为什么引入处理程序会导致这种行为


我的api任务将花费50毫秒到5秒的时间。

在诸如旋转之类的配置更改期间,保留的片段不会被重新创建,但它们仍然会在系统关闭应用程序时被销毁并重新创建,例如,因为它位于后台

因此,为了安全起见,您至少应该:

  • 永远不要将异步任务作为内部类放在片段中,如果您想将其放在片段类主体中,那么就将其设置为静态。否则,AsyncTask将保留对片段的内部引用,并防止对其进行垃圾收集,更糟糕的是,在onPostExecute中,您将访问已销毁的片段

  • 创建asynctask时,将对fragment的引用传递给它,并将此引用存储在WeakReference中,例如:

    private WeakReference fragmentRef

  • 然后在
    onPostExecute
    中,在使用片段之前检查
    fragmentRef.get()
    是否返回非null


    如果需要连续的数据更新,那么考虑使用ItnService,甚至唤醒服务。报告从服务到活动的数据更新进度会稍微困难一些,但可以通过广播进行管理。此外,如果您想从后台更新数据,则必须使用服务和警报-然后WakeFullIntentService(或常规服务)是一种方法:进一步阅读。

    可能我误解了什么。正在讨论的片段是一个保留片段。。。我似乎失去了对主要活动的引用,而不是片段。我考虑过一项服务,但我真的只希望在应用程序处于活动状态时运行更新,而不需要背景活动。也许我的答案与代码中的问题没有严格的相关性,很难说-但我认为这些提示很有帮助。在您的问题中,您会说:
    在引用主活动侦听器时崩溃,您是否会在片段中保留对您的活动的硬引用?如果是,则可能是指onPostExecute中已销毁的活动。您的提示非常有用,只是还没有完全弄清楚“正确答案”是什么。当我使用handler.postDelayed()调用asynctask时,屏幕方向的更改是导致崩溃的原因我可能是天真地看待这个问题,而不理解处理程序或异步任务。该片段更新对活动回调的引用。内部类asynctask确实调用了activities callbacklistener,但没有使用handler.postDelayed()调用。dataListener引用似乎在屏幕更改时得到了正确更新。为什么在处理程序中执行任务会破坏ref