[英]How to prevent Loader from restarting during screen orientation change? - Android
我有一个活动,在RecyclerView中显示食谱列表。 项目的计算成本很高,因此我使用加载程序填充RecyclerView,并且该加载程序缓存数据以防止其重复计算。
显示配方列表后旋转屏幕时,它表现良好(即不重复计算)。 但是,当我在计算过程中旋转屏幕时 ,加载程序会从头开始重新进行计算(因此,例如,如果我每5秒钟旋转一次屏幕,它将永远不会显示任何内容,因为计算大约需要12秒钟)。 另外,如果我单击一个食谱,启动一个新活动,然后旋转屏幕,然后单击以返回到我的食谱列表活动,则加载程序将再次开始计算所有内容。
这是应用程序的可接受行为吗? 如何防止这些重复的计算发生?
我的onCreate在此行中使用加载程序:
getSupportLoaderManager().initLoader(RECIPES_LOADER_ID, null, this);
我的活动以这种方式覆盖了加载程序回调:
@NonNull
@Override
public Loader<List<Recipe>> onCreateLoader(int id, @Nullable Bundle args) {
return new RecipesLoader(this, /* other parameters here */);
}
@Override
public void onLoadFinished(@NonNull Loader<List<Recipe>> loader, List<Recipe> data) {
inventingTextView.setVisibility(View.INVISIBLE);
inventingProgressBar.setVisibility(View.INVISIBLE);
if (data != null) {
recipesAdapter.updateRecipes(data);
}
}
@Override
public void onLoaderReset(@NonNull Loader<List<Recipe>> loader) {
recipesAdapter.updateRecipes(null);
}
我的RecipesLoader是我的活动中的静态嵌套类:
private static class RecipesLoader extends AsyncTaskLoader<List<Recipe>> {
private List<Recipe> recipes = null;
private /* other member variables here */
public RecipesLoader(@NonNull Context context, /* other parameters here */) {
super(context);
/* initializing member variables here */;
}
@Override
protected void onStartLoading() {
super.onStartLoading();
if (recipes != null) {
deliverResult(recipes);
} else {
forceLoad();
}
}
@Nullable
@Override
public List<Recipe> loadInBackground() {
return /* costly computation here */
}
@Override
public void deliverResult(@Nullable List<Recipe> data) {
recipes = data;
super.deliverResult(data);
}
}
首先,请考虑检测用户何时到达列表的末尾,然后与服务器联系,以降低总体加载成本。
无论如何,这是可能的解决方案:
主要活动
public class MainActivity extends Activity {
private List<Recipe> recipes;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
// initialize layout here
restoreState(savedInstanceState);
}
public void restoreState(Bundle state) {
if(state == null) {
// this is the first time activity is created
recipes = new RecipesLoader().loadInBackground();
}else {
// configuration has been changed (e.g. device rotated)
recipes = state.getSerializable("recipes");
}
}
@Override
protected void onSaveInstanceState(Bundle stateToSave) {
super.onSaveInstanceState(stateToSave);
stateToSave.putSerializable("recipes", recipes);
}
}
食谱
public class Recipe implements Serializable {
// must implement Serializable because it will be passed through Intent
. . .
}
顺便说一句,您可以看一下“忙于Android开发的编码员指南”中的第19章,其中介绍了如何处理旋转更改。
对于该活动,请在android Menifest文件中设置android:configChanges=orientation
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.