Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android應用開發:Fragment與大型數據緩存

Android應用開發:Fragment與大型數據緩存

編輯:關於Android編程

引言


在Android應用開發:Fragment的非中斷保存setRetaineInstance一文中已經介紹過了如何讓Fragment不隨著Activity銷毀從而保存數據的方法。在移動應用程序的架構設計中,界面與數據即不可分割又不可混淆。在絕大部分的開發經歷中,我們都是使用Fragment來進行界面編程,即使保存數據基本上也只是界面相關控件的數據,很少做其他的數據保存,畢竟這樣與開發原則相背,而今天這一篇博客就要來介紹一下Fragment的另類用法,只是用來保存數據而沒有任何界面元素。


實現背景


對於Fragment的數據保存方法,不難想到還是與setRetainInstance有關系的。這樣一來所處的背景也是在屏幕旋轉或其他配置改變時需要用到。無論在開發中我們的界面是用Activity還是Fragment生成的,在屏幕發生旋轉時,都會在生命周期onSaveInstanceState中做控件狀態和必要數據的緩存工作。通常情況下,會用到Bundle來存儲數據。如Bundle的官方介紹所說,Bundle是一個用來存儲String及其他序列化數據類型的map。同樣Android中也存在著這樣的一個異常:http://developer.android.com/intl/zh-cn/reference/android/os/TransactionTooLargeException.html


這個異常從字面上看不難理解,是傳輸數據過大異常。在描述中可知,現行Android系統中對於應用程序的傳輸數據大小限制在1Mb以內。所以如果在屏幕旋轉過程中使用Bundle緩存大數據並不是十分安全的。這樣的大數據在Android中很經典的代表之一就是Bitmap,即使Bitmap已經是序列化數據,能夠方便的使用Bundle作為緩存媒介,但是筆者還是強烈不建議這樣做。下邊,就提供一個簡單的解決途徑。


實現過程


首先,創建一個用來保存數據的Fragment:

public class BitmapDataFragment extends Fragment {
    public static final String TAG = "bitmapsaver";
    private Bitmap bitmap;

    private BitmapDataFragment(Bitmap bitmap) {
        this.bitmap = bitmap;
    }

    public static BitmapDataFragment newInstance(Bitmap bitmap) {
        return new BitmapDataFragment(bitmap);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    public Bitmap getData() {
        return bitmap;
    }
}

這個Fragment沒有任何界面,在onCreate生命周期中使用setRetainInstance(true)確保不會隨載體銷毀,從而確保數據的安全性。


創建完成後,實踐一下使用過程,假設其使用者是Activity:


@Override
    protected void onSaveInstanceState(Bundle outState) {
        if (mBitmap != null) {
            getSupportFragmentManager().beginTransaction()
                    .add(BitmapDataFragment.newInstance(mBitmap), BitmapDataFragment.TAG)
                    .commit();
            outState.putBoolean(SENSE_IMAGE_KEY, true);
        } else {
            outState.putBoolean(SENSE_IMAGE_KEY, false);
        }
        super.onSaveInstanceState(outState);
    }

在設備發生旋轉時,檢測當前界面中顯示的某個Bitmap,如果確實有數據,則new出一個我們剛剛創建的Fragment,將Bitmap數據放置進去,然後將這個Fragment添加到FragmentManager中並指定tag,這樣我們在恢復狀態後就可以方便的找到它。


在恢復時候,Activity的生命周期走到了onCreate()中,在這裡我們可以通過檢測Bundle參數來確定是否有Bitmap數據待取:


if (savedInstanceState.getBoolean(SENSE_IMAGE_KEY)) {
     BitmapDataFragment fragment = (BitmapDataFragment) getSupportFragmentManager()
         .findFragmentByTag(BitmapDataFragment.TAG);
     bitmap = fragment.getData();
     getSupportFragmentManager().beginTransaction().remove(fragment).commit();
}

PS:在取出我們所需的Bitmap數據後不要忘記把作為數據容器的這個Fragment從FragmentManager中移除掉,釋放其占用的系統內存。


總結


很簡單的Fragment非主流用法,相比直接使用Bundle保存數據確實是復雜了些,但是能夠更安全的進行數據轉移對應用來說還是很好的一件事。推薦指數五顆星★★★★★!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved