Android組件化架構學習筆記——組件化編程之數據存儲

Android中的五種存儲方式:SharePreferences,File I/O,SQLite,ContentPreferences,網絡。

  • 網絡存儲:一定固定的路徑可以獲取到相關信息;
  • File I/O(文件存儲)便於攜帶和分享;
  • SQLite(數據庫):通過事前管理的機制,數據處理高效;
  • ContentPreferences(內容提供者):跨app傳輸數據,速度取決於存儲數據的獲取的類型和大小;
  • SharePreferences(配置共享):配置存儲,並非專門用於數據持久化存儲。

一.五種存儲方式的基礎原理:

  • 網絡存儲使用http協議或者socket通信作爲傳輸方式。http底層也是通過短時間的socket通信來實現的傳輸。HttpClient很早已經被Android API23廢棄,隨後替換成HttpURLConnection,現在提倡更高效的OkHttp。我們通過一些流行的如retrofit/volley等網絡框架來發送/接收數據,其數據格式一般爲XML,JSON格式。
  • File I/O操作數據通過字節流操作來完成,直接對二進制數據進行處理。
  • SQLite是輕量級數據庫,通過SQLiteOpenHelper來封裝入口,然後調用SQLiteDataBase進行操作,SQLiteConnection中包含許多Native方法,通過JNI與SQLite3進行交互。
  • ContentProvider在不同的應用程序中共享數據時,其數據的暴露方式是採取類似數據庫中表的方法。而ContentResolver恰好採用類似數據看的方法來從ContentProvider中存取數據,通過Uri來查詢ContentProvider中提供的數據。當調用ContentResolver的insert/delete/update/query方法中任何一個時,如ContentProvider所在的進程沒有啓動,則會觸發ContentProvider的創建,並伴隨着ContentProvider所在的進程的啓動,通過Binder機制獲取到Native層實際執行方法的對象。
  • SharePreferences是一種輕量級的數據存儲機制,它將一些簡單數據類型的數據,包括數制類型/String類型數據以鍵值對的形式存儲在應用程序的私有SharePreferences目錄中。通過將鍵值對以XML格式保存到私有的XML文件中,其原理是對XML文件的拼寫修改。

 

二.組件化存儲:

Android原生的存儲體系是全局的,在組件化的開發中,五種原生的存儲方式完全通用的。greenDAO是一種對象關係映射(ORM)的框架,能夠提供一個接口,通過操作對象的方式去操作關係型數據庫,它能夠讓你在操作庫時更簡單方便。其原理是將一個實體對象轉化成一項數據,然後保存到SQLiteDatabase中,底層還是通過操作SQLiteDatabase來完成數據庫操作的。因爲底層使用的是SQLiteDatabase,所以無法保存如圖片這樣大的對象。

greenDAO是目前衆多ORM數據庫中最穩定/速度最快/編寫體驗最好的框架,並且支持RxJava。

  • 註解:@Entity聲明實體對象,@Id聲明索引,@Property聲明的是每個變量帶有的列名,默認@Property(nameInDb="name")。
@Entity
public class SettingsInfo {
    @Id
    private long id;
    private int width;
    private int height;
    private int density;
    private String recordPath;
}
  • 第一次編譯會生成DaoMaster,DaoSession和數據類名Dao文件。
  • 通過封裝一個簡單的DBManger單例來操作Dao接口:
public class DBManger {
    
    private volatile static DBManger instance;
    private final static String dbName = "setting_db";
    private DaoMaster.DevOpenHelper openHelper;
    private SQLiteDatabase db;
    private DaoMaster daoMaster;
    private DaoSession daoSession;
    private Context context;
    
    public static DBManger getInstance() {
        if (instance == null) {
            synchronized (DBManger.class) {
                if (instance == null) {
                    instance = new DBManger();
                }
            }
        }
        return instance;
    }
    
    public DBManger init(Context context) {
        setDataBase(context);
        return this;
    }

    private void setDataBase(Context context) {
        openHelper = new DaoMaster.DevOpenHelper(context,dbName,null);
        db = openHelper.getWritableDatabase();
        daoMaster = new DaoMaster(db);
        daoSession = daoMaster.newSession();
        
    }

    public DaoSession getDaoSession() {
        return daoSession;
    }

    public SQLiteDatabase getDb() {
        return db;
    }
}
  • 獲取SettingInfoDao對象:
        SettingsInfoDao mSIDao = DBManger.getInstance().init(context).getDaoSession().getSettingsInfoDao();
  • 讀取某項數據:
        SettingsInfo settingsInfo = mSIDao.queryBuilder().where(SettingsInfoDao.Properties.Id.eq(0)).unique();
  • 通過Dao對象寫入基礎數據:
        mSIDao.insert(new SettingsInfo(0,1,2,3,"s"));

三.greenDao的優缺點及與Realm對比:

greenDao自動生成了DaoMaster,DaoSession,xxxDao是其優勢的地方,但也有其劣勢的地方:

  • 無法侵入性地在這些文件中進行修改,因爲每次編譯都會重新編譯生成(替換)這些文件,無法在其中做任何操作;
  • greenDao每次編譯都會替換編譯時註解生成的文件。

Realm在性能是插入和查詢速度要優於greenDao,刪除速度greenDao會較快;

需要考量的是greenDao的體積遠少於Realm,因爲greenDao使用Android底層的SQLite3,而Realm使用本身的數據庫查詢引擎,需要引入額外的so庫。Realm支持JSON和流式API也是優勢,另外也支持RxJava。

 

四.組件化數據庫:

原生的數據庫的運用範圍是整個app。但是當組件化使用關係型數據庫的時候,就需要考量解耦的問題。

問題的關鍵在與ORM原理——將實體對象轉化爲數據映射。原生數據庫是運用是直接對SQLiteDatabase進行數據庫操作,所以需要自身封裝對象。實體類放在本身的module中是無法傳遞的,需要放在一個統一的module中來管理這些類的產生和引用,其greenDao需要在Base module中引入,編寫時註解生成對象也應該放在Base module中,這樣全部的功能模塊才能引用到這個數據。

另一種是將數據庫層獨立爲一個模塊爲隨後的管理層,數據層將抽離/封裝和調用都可以統一XXXData的module中完成,這種組件是從Base基礎層分離出來的組件模塊,屬於更低的框架層。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章