Android 方向更改后使用存储库模式获取数据

Android 方向更改后使用存储库模式获取数据,android,repository-pattern,Android,Repository Pattern,我有一个关于方向改变的问题。 在我的应用程序中,我使用了MVP+改装+RxKotlin和存储库模式。应用程序开放数据通过存储库从API下载-一切都很好。在我旋转设备之后,我想知道如何在不再次询问API的情况下获取数据。我应该在第一次下载后将数据保存到DB,还是应该做一些不同的事情?这是我在应用程序上处理数据的方式,我也在使用ViewModel+Repository模式: 首先,确保您的存储库对象具有应用程序范围,这样它也能在片段和活动的破坏中幸存下来 由于您的ViewModel将在屏幕旋转后仍

我有一个关于方向改变的问题。
在我的应用程序中,我使用了
MVP
+
改装
+
RxKotlin
存储库模式
。应用程序开放数据通过存储库从API下载-一切都很好。在我旋转设备之后,我想知道如何在不再次询问API的情况下获取数据。我应该在第一次下载后将数据保存到
DB
,还是应该做一些不同的事情?

这是我在应用程序上处理数据的方式,我也在使用ViewModel+Repository模式:

  • 首先,确保您的存储库对象具有应用程序范围,这样它也能在片段和活动的破坏中幸存下来
  • 由于您的ViewModel将在屏幕旋转后仍然存在,所以请在ViewModel的内存中保留获取数据的缓存。例如:如果让UI在ViewModel中观察LiveData,并在存储库返回时在LiveData中设置值,LiveData将保留最后发出的值,因此当UI再次订阅时,您将立即获得数据
  • 而且,由于您的片段将被重新创建,您将再次调用fetch,但是在您的ViewModel中,您可以保存并检查您是否已经使用相同的参数和URL进行了网络调用,并忽略它。(注意:如果savedInstanceState为非null,则不要放置筛选器以避免重新获取,这并不总是正确的)
这是一个想法,你可以用自己的方式适应


我的主要观点是,ViewModel可以帮助您在任何类型的配置更改中生存下来,而不会重新获取数据或丢失屏幕状态。尝试始终使您的ViewModel有状态,使您的UI无状态,因此您的UI的唯一责任是反映ViewModel的任何状态。

这是我在应用程序上处理的方式,我也在使用ViewModel+存储库模式:

  • 首先,确保您的存储库对象具有应用程序范围,这样它也能在片段和活动的破坏中幸存下来
  • 由于您的ViewModel将在屏幕旋转后仍然存在,所以请在ViewModel的内存中保留获取数据的缓存。例如:如果让UI在ViewModel中观察LiveData,并在存储库返回时在LiveData中设置值,LiveData将保留最后发出的值,因此当UI再次订阅时,您将立即获得数据
  • 而且,由于您的片段将被重新创建,您将再次调用fetch,但是在您的ViewModel中,您可以保存并检查您是否已经使用相同的参数和URL进行了网络调用,并忽略它。(注意:如果savedInstanceState为非null,则不要放置筛选器以避免重新获取,这并不总是正确的)
这是一个想法,你可以用自己的方式适应


我的主要观点是,ViewModel可以帮助您在任何类型的配置更改中生存下来,而不会重新获取数据或丢失屏幕状态。始终尝试使ViewModel有状态,使UI无状态,因此UI的唯一责任是反映ViewModel的任何状态。

您不需要在ViewPager片段中进行API调用,也不应该在活动中进行此操作。相反,您可以在主活动中添加一个片段。该片段将是您的父片段。在父片段的
onCreate()
中,进行API调用。然后使用父片段中的单个子片段创建ViewPager。确保在创建ViewPager适配器时,按如下方式传入子FragmentManager实例:

public class ParentFragment extends Fragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
        API.getData(); //Make API call; has to be done on a separate thread using an AsyncTask or an IntentService. When Data is successfully retrieved, save it to a field in this Fragment.
        //Create ViewPager adapter here like this:
        viewPagerAdapter = new MainVPAdapter(getChildFragmentManager()); //<- important
    }
}
公共类ParentFragment扩展了片段{
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setRetainInstance(真);
API.getData();//进行API调用;必须使用AsyncTask或IntentService在单独的线程上完成。成功检索数据后,将其保存到此片段中的字段中。
//在此处创建ViewPager适配器,如下所示:

viewPagerAdapter=new MainVPAdapter(getChildFragmentManager());//您不需要在ViewPager片段中进行API调用,也不应该在活动中进行调用。相反,您可以在主活动中添加片段。该片段将是您的父片段。在父片段的
onCreate()中
是进行API调用的地方。然后使用父片段中的单个子片段创建ViewPager。请确保在创建ViewPager适配器时传入子片段管理器实例,如下所示:

public class ParentFragment extends Fragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
        API.getData(); //Make API call; has to be done on a separate thread using an AsyncTask or an IntentService. When Data is successfully retrieved, save it to a field in this Fragment.
        //Create ViewPager adapter here like this:
        viewPagerAdapter = new MainVPAdapter(getChildFragmentManager()); //<- important
    }
}
公共类ParentFragment扩展了片段{
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setRetainInstance(真);
API.getData();//进行API调用;必须使用AsyncTask或IntentService在单独的线程上完成。成功检索数据后,将其保存到此片段中的字段中。
//在此处创建ViewPager适配器,如下所示:

viewPagerAdapter=new MainVPAdapter(getChildFragmentManager());//您是否尝试过在活动中使用片段,然后调用
setRetainInstance(true)
,然后仅在
onCreate()
中使用片段,使用
setRetainInstance(true)进行API调用
将仅在首次创建片段时进行API调用。之后,当您执行旋转时,它将不会调用片段的
onCreate()
方法,但将保留您第一次从API调用中检索到的数据。@DavidVelasquez我正在从
活动
级别提取数据,然后将其发送到
查看页面
中的片段,因此基本上不起作用。也许我会改变方法,将数据提取移到
片段
级别。谢谢。请参阅my回答您是否尝试过在活动中使用片段,然后调用
setR