簡體   English   中英

如何防止Loader在屏幕方向更改期間重新啟動? -安卓

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM