Android MVP - 为多个片段重用共享数据
Android MVP - Reuse shared data for multiple fragments
我正在使用 MVP 构建一个 Android 应用程序。
其中一个屏幕以一种 Master/Detail 视图(嵌入播放器的内容页面)显示数据:
顶部是播放器(片段),下面是内容信息(带有片段的viewpager),用户可以在页面(ViewPager)之间滑动以在内容之间切换。当Viewpager位置改变时,播放器相应更新并开始播放当前内容。
演示者请求的数据来自存储库,具有本地(数据库)/远程(Rest API)数据源。
如何充分利用 MVP 来避免多次请求相同的数据?
我是否应该在我的 Activity 中只有一个 Presenter,并且 persist/cache 请求某处的 Content Info 数据,以便在位置改变时将其传回给播放器?
还是为每个 ContentInfo 设置一个 Presenter,请求自己的数据,为播放器设置一个 Presenter,在调用 play() 方法时再次请求相同的数据?
我找到了 相关主题,但它并不适合我的情况,因为播放器中的数据不会在内容信息片段中请求的同时更新(我我正在通过 ViewPager 获取片段的 onCreate 数据,以便在滑动完成时加载它)。
最好的方法是让各个组件从存储库请求数据,并在存储库级别处理缓存。
当ViewPager的内容发生变化时,只需通知播放器一个新内容的ID即可。然后播放器将从存储库中获取此内容。该内容已经下载的存储库 "knows" 并从数据库而不是 Web 提供。
如果数据库不够快,可以在存储库中实现内存缓存。
您可以使用 Fragment
和 setRetainInstance(true)
作为数据片段。 setRetainInstance
控制片段实例是否在 Activity 重新创建(例如从配置更改)中保留。
此处的数据片段示例:
public class MyDataFragment extends Fragment {
public static MyDataFragment newInstance() {
return new MyDataFragment();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retain this instance so it isn't destroyed when MainActivity and MainFragment change configuration.
setRetainInstance(true);
}
// Add any data you want to share across multiple fragments of same activity here
public String myData = null;
}
假设 Activity class 被命名为 MyActivity
:
public class MyActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
....
// Build up a common data fragment to be used by multiple child view pager fragments.
final FragmentManager fm = getSupportFragmentManager();
MyDataFragment myDataFragment = (MyDataFragment)fm.findFragmentByTag(MY_DATA_FRAGMENT);
if (myDataFragment == null) {
MyDataFragment dataFragment = MyDataFragment.newInstance();
fm.beginTransaction().add(dataFragment, MY_DATA_FRAGMENT).commit();
}
.....
}
....
public static final String MY_DATA_FRAGMENT = "MY_DATA_FRAGMENT";
然后在您的 player fragment
或 viewpager fragment
中,像这样访问数据片段:
@Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// access data fragment
final FragmentManager fm = getFragmentManager();
this.myDataFragment = (MyDataFragment)fm.findFragmentByTag(MyActivity.MY_DATA_FRAGMENT);
.....
}
@Override
public void onResume() {
super.onResume();
if (myDataFragment.myData != null) {
// data already exists, SKIP to make network call. Process it directly, eg: update UI
.....
} else {
// fetch data from network via asynchronously task ---- [1]
// assume upon finish, the asynchronously task will invoke "onDataLoadFinish()" method below:
....
}
}
// assume this will be invoked by asynchronously network task [1] above
public void onDataLoadFinish (String data) {
// set data to data fragment, which can be reused by multiple fragments
this.myDataFragment.myData = data;
}
.....
private MyDataFragment myDataFragment = null;
希望对您有所帮助,祝您好运!
我正在使用 MVP 构建一个 Android 应用程序。 其中一个屏幕以一种 Master/Detail 视图(嵌入播放器的内容页面)显示数据:
顶部是播放器(片段),下面是内容信息(带有片段的viewpager),用户可以在页面(ViewPager)之间滑动以在内容之间切换。当Viewpager位置改变时,播放器相应更新并开始播放当前内容。
演示者请求的数据来自存储库,具有本地(数据库)/远程(Rest API)数据源。
如何充分利用 MVP 来避免多次请求相同的数据?
我是否应该在我的 Activity 中只有一个 Presenter,并且 persist/cache 请求某处的 Content Info 数据,以便在位置改变时将其传回给播放器?
还是为每个 ContentInfo 设置一个 Presenter,请求自己的数据,为播放器设置一个 Presenter,在调用 play() 方法时再次请求相同的数据?
我找到了
最好的方法是让各个组件从存储库请求数据,并在存储库级别处理缓存。
当ViewPager的内容发生变化时,只需通知播放器一个新内容的ID即可。然后播放器将从存储库中获取此内容。该内容已经下载的存储库 "knows" 并从数据库而不是 Web 提供。
如果数据库不够快,可以在存储库中实现内存缓存。
您可以使用 Fragment
和 setRetainInstance(true)
作为数据片段。 setRetainInstance
控制片段实例是否在 Activity 重新创建(例如从配置更改)中保留。
此处的数据片段示例:
public class MyDataFragment extends Fragment {
public static MyDataFragment newInstance() {
return new MyDataFragment();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retain this instance so it isn't destroyed when MainActivity and MainFragment change configuration.
setRetainInstance(true);
}
// Add any data you want to share across multiple fragments of same activity here
public String myData = null;
}
假设 Activity class 被命名为 MyActivity
:
public class MyActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
....
// Build up a common data fragment to be used by multiple child view pager fragments.
final FragmentManager fm = getSupportFragmentManager();
MyDataFragment myDataFragment = (MyDataFragment)fm.findFragmentByTag(MY_DATA_FRAGMENT);
if (myDataFragment == null) {
MyDataFragment dataFragment = MyDataFragment.newInstance();
fm.beginTransaction().add(dataFragment, MY_DATA_FRAGMENT).commit();
}
.....
}
....
public static final String MY_DATA_FRAGMENT = "MY_DATA_FRAGMENT";
然后在您的 player fragment
或 viewpager fragment
中,像这样访问数据片段:
@Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// access data fragment
final FragmentManager fm = getFragmentManager();
this.myDataFragment = (MyDataFragment)fm.findFragmentByTag(MyActivity.MY_DATA_FRAGMENT);
.....
}
@Override
public void onResume() {
super.onResume();
if (myDataFragment.myData != null) {
// data already exists, SKIP to make network call. Process it directly, eg: update UI
.....
} else {
// fetch data from network via asynchronously task ---- [1]
// assume upon finish, the asynchronously task will invoke "onDataLoadFinish()" method below:
....
}
}
// assume this will be invoked by asynchronously network task [1] above
public void onDataLoadFinish (String data) {
// set data to data fragment, which can be reused by multiple fragments
this.myDataFragment.myData = data;
}
.....
private MyDataFragment myDataFragment = null;
希望对您有所帮助,祝您好运!