關(guān)于android architecture Component的入門資料

前不久Google IO 2017不僅將kotlin宣布為官方開發(fā)語言,還發(fā)布了谷歌官方 Android 應(yīng)用架構(gòu)庫(kù),這個(gè)新的架構(gòu)庫(kù)旨在幫助我們?cè)O(shè)計(jì)健壯菇肃、可測(cè)試的和可維護(hù)的應(yīng)用程序蜕着。新項(xiàng)目也打算采用這套架構(gòu),下面一步步介紹怎么去配置和使用這套架構(gòu)尚蝌。(最簡(jiǎn)單介紹,詳細(xì)內(nèi)容看官方文檔和其他參考資料)

總覽

http://upload-images.jianshu.io/upload_images/1794675-daff0735135762ce.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

簡(jiǎn)單說來充尉,該架構(gòu)由數(shù)據(jù)驅(qū)動(dòng)飘言, 徹底將UI和data分離,UI層很輕驼侠,不涉及任何數(shù)據(jù)的操作的內(nèi)容姿鸿。ViewModel將數(shù)據(jù)的變化的反映在UI上,本身也不持有數(shù)據(jù)倒源。官方推薦所有數(shù)據(jù)持久化苛预。viewmodel通過Repository來管理數(shù)據(jù),保存到數(shù)據(jù)庫(kù)或者從網(wǎng)絡(luò)獲取笋熬。

kotlin的配置

本次打算使用kotlin來進(jìn)行開發(fā)

新建一個(gè)項(xiàng)目热某,完成后在project/build.gradle添加以下內(nèi)容

//對(duì)照添加
buildscript {
    ext.kotlin_version = '1.1.2-5'
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

在app/build.gradle的開頭添加:

apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

簡(jiǎn)單解釋:
第二行表示kotlin擴(kuò)展,可以避免使用類似findviewbyid的很多內(nèi)容
第三行表示kotlin對(duì)注解的處理胳螟,感覺對(duì)databinding的支持不是很好苫拍。
到此為止, kotlin的配置已經(jīng)完成旺隙。

在android studio的插件中安裝kotlin后重啟绒极。
對(duì)Mainactivity.java執(zhí)行code--convert java file to koltin file。
編譯運(yùn)行成功的話蔬捷,說明kotlin配置成功

android architecture Component的配置

該架構(gòu)官方翻譯參考:https://juejin.im/post/5937b1d7a22b9d005810b877

簡(jiǎn)單配置如下
在project/build.gradle中添加:

allprojects {
    repositories {
        jcenter()
        maven { url 'https://maven.google.com' }
    }
}

在app/build.gradle中添加

    /// Architecture Components
    compile "android.arch.lifecycle:runtime:$ac_version"
    compile "android.arch.lifecycle:extensions:$ac_version"
    kapt "android.arch.lifecycle:compiler:$ac_version"
    /// Room
    compile "android.arch.persistence.room:runtime:$ac_version"
    kapt "android.arch.persistence.room:compiler:$ac_version"

前面三行是關(guān)于lifecycle垄提,livedata榔袋, viewmodel的依賴,后面是關(guān)于Room的依賴铡俐。
后面用例子進(jìn)行說明凰兑。如有問題歡迎討論。

Room的使用

Room在sqlite之上提供了一個(gè)抽象層审丘。
將數(shù)據(jù)持久化到本地對(duì)于應(yīng)用程序處理大量結(jié)構(gòu)化數(shù)據(jù)有非常大的好處吏够。最常見的情況是緩存相關(guān)數(shù)據(jù)。這樣滩报,當(dāng)設(shè)備無法訪問網(wǎng)絡(luò)時(shí)锅知,用戶仍然可以在離線狀態(tài)下瀏覽內(nèi)容。然后脓钾,在設(shè)備重新上線后售睹,任何用戶發(fā)起的內(nèi)容變更都會(huì)同步到服務(wù)器。
其中有三個(gè)組件組成:

  • DataBase
  • Entity
  • DAO

下面介紹最簡(jiǎn)單的使用方法:

項(xiàng)目結(jié)構(gòu):(https://github.com/yunshuipiao/SWBlog/blob/master/media/android%20architecture%20Component/%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84.png)

如上圖所示可训,項(xiàng)目結(jié)構(gòu)對(duì)應(yīng)架構(gòu)圖昌妹,另外的base,App是一些基礎(chǔ)的ui握截, 項(xiàng)目的app單例飞崖,以后還會(huì)添加dagger2來分離模塊。
新建一個(gè)Story文件谨胞,內(nèi)容如下:

@Entity(tableName = "stories")
class Story {
    @PrimaryKey
    var id = 0
    var data = ""
    var displayData = ""
    var title = ""
    var image = ""
}
//story作為數(shù)據(jù)庫(kù)的一張表固歪,可以指定列名,主鍵

新建StoryDao文件:

@Dao
interface StoryDao {
    @Query("select * from stories")
    fun loadAllStories(): LiveData<List<Story>>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertStories(list: List<Story>)
}
//對(duì)數(shù)據(jù)的操作畜眨,這里涉及插入和查詢(查詢的返回值可以是LiveData,list术瓮, Rxjava2等)

新建AppDatabase文件:

@Database(entities = arrayOf(Story::class), version = 1)
abstract class AppDatabase: RoomDatabase() {
    companion object {
        val TAG = "sw_story_db"
    }
    abstract fun storyDao(): StoryDao
}
//數(shù)據(jù)庫(kù)康聂, 通過dao操作數(shù)據(jù)。

完成這三個(gè)文件胞四,表示Room組件已經(jīng)可以使用恬汁。
新建DataBaseManager文件:

object DatabaseManager {

    lateinit var db: AppDatabase

    fun initDb(context: Context) {
        db = Room.databaseBuilder(context, AppDatabase::class.java, AppDatabase.TAG).build()
    }

    fun insertStories(storys: List<Story>) {
        Flowable.just(storys)
                .observeOn(Schedulers.io())
                .subscribe {
                    db.beginTransaction()
                    try {
                        db.storyDao().insertStories(storys)
                        db.setTransactionSuccessful()
                    } finally {
                        db.endTransaction()
                    }
                }
    }
    fun loadAllStories(): LiveData<List<Story>> {
        return db.storyDao().loadAllStories()
    }

    fun simlutateInsertData() {
        var list = ArrayList<Story>()

        for (i in 1..20) {
            var s = Story()
            s.id = (i)
            s.data = ((i * i).toString() + "--" + i.toString())
            s.displayData = ((i * i).toString() + "--" + i.toString())
            s.title = ((i * i).toString() + "--" + i.toString())
            s.image = ((i * i).toString() + "--" + i.toString())
            list.add(s)
        }
        insertStories(list)
    }
}
//該單例對(duì)數(shù)據(jù)庫(kù)封裝了一層,方便處理db的各種操作(db初始化可使用依賴注入)
數(shù)據(jù)庫(kù)插入不能在主線程辜伟,涉及事務(wù)氓侧。

到此為止,該框架的數(shù)據(jù)庫(kù)部分已經(jīng)可以使用导狡。
下面作為例子說明怎么存數(shù)據(jù)约巷。

//繼承Appication,初始化并模擬插入數(shù)據(jù)
class ZhiJokeApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        DatabaseManager.initDb(this)
        DatabaseManager.simlutateInsertData()
    }
}

編譯項(xiàng)目運(yùn)行旱捧,此時(shí)真機(jī)上應(yīng)該保存有插入的數(shù)據(jù)独郎。

怎么查看

用一臺(tái)已經(jīng)root后的測(cè)試機(jī)踩麦,安裝root文件管理器后,在根目錄的 data/data/包名/database氓癌, 就能看到數(shù)據(jù)庫(kù)新建并插入的數(shù)據(jù)了谓谦。
數(shù)據(jù)(https://github.com/yunshuipiao/SWBlog/blob/master/media/android%20architecture%20Component/%E6%95%B0%E6%8D%AE%E5%BA%93%E8%A1%A8.png)

DatabaseManage.loadAllStories()即可取出數(shù)據(jù)。

未玩待續(xù)

完整代碼:github

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贪婉,一起剝皮案震驚了整個(gè)濱河市反粥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疲迂,老刑警劉巖才顿,帶你破解...
    沈念sama閱讀 218,607評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異鬼譬,居然都是意外死亡娜膘,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門优质,熙熙樓的掌柜王于貴愁眉苦臉地迎上來竣贪,“玉大人,你說我怎么就攤上這事巩螃⊙菰酰” “怎么了?”我有些...
    開封第一講書人閱讀 164,960評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵避乏,是天一觀的道長(zhǎng)爷耀。 經(jīng)常有香客問我,道長(zhǎng)拍皮,這世上最難降的妖魔是什么歹叮? 我笑而不...
    開封第一講書人閱讀 58,750評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮铆帽,結(jié)果婚禮上咆耿,老公的妹妹穿的比我還像新娘。我一直安慰自己爹橱,他們只是感情好萨螺,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著愧驱,像睡著了一般慰技。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上组砚,一...
    開封第一講書人閱讀 51,604評(píng)論 1 305
  • 那天吻商,我揣著相機(jī)與錄音,去河邊找鬼糟红。 笑死手报,一個(gè)胖子當(dāng)著我的面吹牛蚯舱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播掩蛤,決...
    沈念sama閱讀 40,347評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼枉昏,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了揍鸟?” 一聲冷哼從身側(cè)響起兄裂,我...
    開封第一講書人閱讀 39,253評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎阳藻,沒想到半個(gè)月后晰奖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,702評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡腥泥,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評(píng)論 3 336
  • 正文 我和宋清朗相戀三年匾南,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛔外。...
    茶點(diǎn)故事閱讀 40,015評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蛆楞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出夹厌,到底是詐尸還是另有隱情豹爹,我是刑警寧澤,帶...
    沈念sama閱讀 35,734評(píng)論 5 346
  • 正文 年R本政府宣布矛纹,位于F島的核電站臂聋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏或南。R本人自食惡果不足惜孩等,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望采够。 院中可真熱鬧肄方,春花似錦、人聲如沸吁恍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冀瓦。三九已至,卻和暖如春写烤,著一層夾襖步出監(jiān)牢的瞬間翼闽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工洲炊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留感局,地道東北人尼啡。 一個(gè)月前我還...
    沈念sama閱讀 48,216評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像询微,于是被迫代替她去往敵國(guó)和親崖瞭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容