片段异步接口回调处理

时间:2016-08-04 08:33:06

标签: android android-fragments asynchronous

我有一个Fragment通过一些助手Class与互联网进行一些通信,需要一个接口来处理这样的异步回调:

SomeInternetCommunicator.getResource(theResourceToGet, retrieverInterfaceInstance);

界面如下所示:

public interface SomeInternetCommunicator {
     void onResourceRetrieveSuccess(SomeResource resource);
     void onResourceRetrieveFailed(CommunicatorException e);
}

问题在于,有时通话时间过长,用户已经在其他位置导航,而Fragment调用的getResource不再是当前正在运行的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位于BackstackFragmentViewPager加载。

在进行后期处理之前,是否有更好的方法可以确保Fragment仍在当前Activity的范围内?也许正在检查isAdded()

This question似乎解释了一个更广泛但相关的情况,但它没有答案。

谢谢!

1 个答案:

答案 0 :(得分:2)

这种情况有两种常用方法:

  1. 最好的方法是有办法从SomeInternetCommunicator清除界面实例。类似的东西:
  2. @Override public void onDestroyView(){
       SomeInternetCommunicator.removeMe(this);
    }
    
    1. 如果因为SomeInternetCommunicator是编码不良的库而无法使用选项(1),则可以通过创建单独的类来实现接口来强制选项1。
    2. 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