Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/195.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 当片段被替换时停止异步任务_Android_Android Fragments_Android Asynctask - Fatal编程技术网

Android 当片段被替换时停止异步任务

Android 当片段被替换时停止异步任务,android,android-fragments,android-asynctask,Android,Android Fragments,Android Asynctask,在我的片段中,有两个异步任务持续运行。要求是,当用户使用抽屉菜单切换到不同的框架时,应取消这些任务。但是,当用户按下home按钮时,这些任务应保持运行 我在该片段中使用了以下代码: @Override public void onStop() { super.onStop(); if(asyncTripWaiter != null && asyncTripWaiter.getStatus() == AsyncTask.Status.RUNNING)

在我的片段中,有两个异步任务持续运行。要求是,当用户使用抽屉菜单切换到不同的框架时,应取消这些任务。但是,当用户按下home按钮时,这些任务应保持运行

我在该片段中使用了以下代码:

@Override
public void onStop() {
    super.onStop();

    if(asyncTripWaiter != null && asyncTripWaiter.getStatus() == AsyncTask.Status.RUNNING)
        asyncTripWaiter.cancel(true);

    if(asyncTripTracker != null && asyncTripTracker.getStatus() == AsyncTask.Status.RUNNING)
        asyncTripTracker.cancel(true);
} 
public void cancelAllTasks(){
    // your logic to cancel tasks
}

问题是,即使按下home按钮,这段代码也会执行。只有当片段被切换时,我如何才能使其有效。

您可以这样尝试

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (!isVisibleToUser) {
        if(asyncTripWaiter != null && asyncTripWaiter.getStatus() == AsyncTask.Status.RUNNING)
            asyncTripWaiter.cancel(true);

        if(asyncTripTracker != null && asyncTripTracker.getStatus() == AsyncTask.Status.RUNNING)
            asyncTripTracker.cancel(true);
    }
}

setUserVisibleHint()是fragment类的重写方法

因为您只需要在切换时取消,所以这样做的一种方法是公开
片段的一些公共函数

片段的切换很可能发生在
活动中,因此在替换之前,调用片段的公开函数以取消异步任务

e、 g

在你的片段中:

@Override
public void onStop() {
    super.onStop();

    if(asyncTripWaiter != null && asyncTripWaiter.getStatus() == AsyncTask.Status.RUNNING)
        asyncTripWaiter.cancel(true);

    if(asyncTripTracker != null && asyncTripTracker.getStatus() == AsyncTask.Status.RUNNING)
        asyncTripTracker.cancel(true);
} 
public void cancelAllTasks(){
    // your logic to cancel tasks
}
在活动中:

yourFragment.cancelAllTasks();
...
replaceAnotherFragmentCode();
不是那么简单, 请考虑当你的片段要返回堆栈时的情况,然后你可以使用方法<代码> OnPAUSEE()/<代码>和<代码> OnStutter()/<代码>。 用户可以在
AsyncTask
仍在运行时立即返回此片段。 那么,再次调用
AsyncTask
可能不是很有效

其实有两个选择,, 第一个是同步架构解决方案,当您将模型与可见片段分开同步时,您不必取消
AsyncTask
,但需要更改应用程序逻辑。 你可以在电视上听到 正如讲师所说,拥有什么样的体系结构并不重要,但重要的是如何处理数据加载和缓存

因此,第一种选择是将数据与片段和活动分开缓存

第二个选项是保持
AsyncTask
处于活动状态,但检查是否对活动任务进行分段,和/或缓存数据,即使数据不存在。用户可以稍后返回此片段

fragment
销毁时,这不会发生,因此您可以监听
ondestory
方法并设置标志,如
destromed=true。
当
AsyncTask
返回时,您可以检查

if (!destroyed) { 
    // do your job
}

添加asyncTripTracker.cancel(true);在片段重放您的取消代码的活动中,您在其中放置了切换片段的条件。我做了类似的操作,最接近的匹配是您的答案,感谢+1将片段和异步任务分开。比如说asynctask完成了它的工作,然后我们再决定是否使用它。