我有一个Fragment
,它通过一些助手Class
与互联网进行一些通信,需要一个接口来处理异步回调,如下所示:
SomeInternetCommunicator.getResource(theResourceToGet, retrieverInterfaceInstance);
界面如下:
public interface SomeInternetCommunicator {
void onResourceRetrieveSuccess(SomeResource resource);
void onResourceRetrieveFailed(CommunicatorException e);
}
问题是,有时调用时间太长,用户已经导航到其他位置,并且对getResource
进行调用的Fragment
不再是当前运行的Activity
的一部分(不显示,不在后台)。这导致了许多问题,因为这个孤立的Fragment
仍然试图对回调做出反应,即使它不再是Activity
的一部分。例如,getContext()
返回null。
现在我在Fragment
上的解决方法如下:
SomeInternetCommunicator flocktrackerTrackerRetrieverInterface = new SomeInternetCommunicator() {
@Override
public void onResourceRetrieveSuccess(SomeResource resource) {
if(isVisible()){
doRetrievalPostProcessing(resource);
}
}
@Override
void onResourceRetrieveFailed(CommunicatorException e) {
if(isVisible()){
doExceptionHandling();
}
}
};
使用isVisible()
是有效的,因为这确保了片段仍然在前台,是Activity
的一部分,并准备好进行处理。然而,这并不能帮助我涵盖Fragment
不可见,但仍然是当前Activity
的一部分的情况,这限制了我在显示之前加载Fragment
的可能性。(Activity
在后台,Fragment
在Backstack
上,Fragment
由ViewPager
加载)。
在我进行后处理之前,有没有更好的方法来确保Fragment
仍然在当前Activity
的范围内?也许检查isAdded()
?
这个问题似乎解释了一个更广泛但相关的情况,但它没有答案。
谢谢!
有两种常见的方法来处理这种情况:
- 最好的方法是有一种方法从CCD_ 23中清除接口实例。类似于:
@Override public void onDestroyView(){
SomeInternetCommunicator.removeMe(this);
}
- 如果选项(1)不可能,因为
SomeInternetCommunicator
是一个编码不好的库,那么通过创建一个单独的类来实现接口,可以强制选项1成为可能
public class SomeInternetCommunicatorInterceptor implements SomeInternetCommunicatorInterface {
private SomeInternetCommunicatorInterface listener;
public void setListener(SomeInternetCommunicatorInterface listener){
this.listener=listener;
}
@Override
public void onResourceRetrieveSuccess(SomeResource resource){
if(listener != null){
listener.onResourceRetrieveSuccess(resource);
}
}
@Override
public void onResourceRetrieveFailed(CommunicatorException e){
if(listener != null){
listener.onResourceRetrieveFailed(e);
}
}
}
然后在你的片段上,你使用这个新类作为:
private SomeInternetCommunicatorInterceptor interceptor;
public void onCreateView(....){
... your code
interceptor = new SomeInternetCommunicatorInterceptor();
}
onStart(){
interceptor.setListener(this);
}
onStop(){
interceptor.setListener(null);
}
public void onDestroyView(){
interceptor = null;
super.onDestroyView();
}
非常重要:
如果您使SomeInternetCommunicatorInterceptor
成为片段的内部类,则必须使其成为static class