Google Architecture Components 使用

来源:互联网 发布:c语言第四章答案 编辑:程序博客网 时间:2024/04/24 15:03

architecture components使用google新推出的Android 架构组件,目标是帮助我们设计更好、可测试和可维护应用程序。它可以自动管理UI组件生命周期,也能处理数据持久化的问题。

现在的稳定版本是1.0
官网地址
Demo项目地址

环境

  • 编译器:Android Studio3.0
  • 开发语言:kotlin

接入

接入方式还算比较简单
在Project的build.gradle添加

buildscript {    ext.ac_version='1.0.0'    repositories {        google()    }}

在app的build.gradle添加

apply plugin: 'kotlin-kapt'dependencies {    /// Architecture Components    implementation "android.arch.lifecycle:runtime:$ac_version"    implementation "android.arch.lifecycle:extensions:$ac_version"    kapt "android.arch.lifecycle:compiler:$ac_version"    /// Room    implementation "android.arch.persistence.room:runtime:$ac_version"    kapt "android.arch.persistence.room:compiler:$ac_version"}

这样写完后依赖库就添加完成了。

使用

首先我们创建一个MainActivity
布局文件我们可以这样写

<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.bobbygu.googlearchitecture.MainActivity">    <TextView        android:id="@+id/tv1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:gravity="center"        android:text="Google Architecture框架\n数据持久化"        app:layout_constraintBottom_toBottomOf="parent"        app:layout_constraintLeft_toLeftOf="parent"        app:layout_constraintRight_toRightOf="parent"        app:layout_constraintTop_toTopOf="parent"        app:layout_constraintVertical_bias="0.01" />    <Button        android:id="@+id/btn_insert"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="8dp"        android:text="模拟插入"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toBottomOf="@+id/tv_title" />    <Button        android:id="@+id/btn_delete_all"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="删除所有"        app:layout_constraintStart_toEndOf="@+id/btn_insert"        app:layout_constraintTop_toTopOf="@+id/btn_insert" />    <Button        android:id="@+id/btn_get_data"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="获取数据"        app:layout_constraintStart_toEndOf="@+id/btn_delete_all"        app:layout_constraintTop_toTopOf="@+id/btn_insert" />    <TextView        android:id="@+id/tv2"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_marginEnd="8dp"        android:layout_marginStart="8dp"        android:maxLines="10"        android:minLines="1"        android:scrollbars="vertical"        android:text="数据库数据显示"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toBottomOf="@+id/btn_insert_one" />    <TextView        android:id="@+id/tv_title"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="数据库操作:"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toBottomOf="@+id/tv1" />    <Button        android:id="@+id/btn_insert_one"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginEnd="8dp"        android:layout_marginStart="8dp"        android:layout_marginTop="8dp"        android:text="插入一个"        app:layout_constraintEnd_toStartOf="@+id/btn_delete_all"        app:layout_constraintStart_toStartOf="@+id/btn_insert"        app:layout_constraintTop_toBottomOf="@+id/btn_insert" />    <Button        android:id="@+id/btn_delete_one"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="删除一个"        app:layout_constraintStart_toEndOf="@+id/btn_insert_one"        app:layout_constraintTop_toTopOf="@+id/btn_insert_one" /></android.support.constraint.ConstraintLayout>

这里写图片描述
ConstraintLayout使用不熟练的话可以看这个:ConstraintLayout 完全解析 快来优化你的布局吧

MainActivity.kt是这样的

class MainActivity : AppCompatActivity() {    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)        tv2.movementMethod = ScrollingMovementMethod.getInstance()        DatabaseManager.initDb(this)        val model = ViewModelProviders.of(this).get(MyViewModel::class.java)        model.users.observe(this, Observer { users ->            if (users != null && users.isNotEmpty()) {                tv1.text = users[0].name            }        })        model.stories.observe(this, Observer { stories ->            Log.d("Main", "stories:" + stories)            if (stories != null) {                var str = ""                for (story in stories) {                    str += "title:" + story.title + "\n"                }                tv2.text = str            }        })        btn_insert.setOnClickListener {            DatabaseManager.simlutateInsertData()        }        btn_insert_one.setOnClickListener {            val story = Story()            story.data = "BobbyApp"            story.displayData = "BobbyApp displayData"            story.title = "BobbyApp" + System.currentTimeMillis()            DatabaseManager.insertStory(story)        }        btn_delete_all.setOnClickListener {            //访问数据库需要到子线程            Thread({                DatabaseManager.deleteAllStories()            }).start()        }        btn_delete_one.setOnClickListener {            DatabaseManager.deleteStory()        }        btn_get_data.setOnClickListener {            DatabaseManager.loadAllStories().observe(this, Observer { stories ->                model.stories.value = stories            })        }    }}

ViewModel

源码:

public abstract class ViewModel {    /**     * This method will be called when this ViewModel is no longer used and will be destroyed.     * <p>     * It is useful when ViewModel observes some data and you need to clear this subscription to     * prevent a leak of this ViewModel.     */    @SuppressWarnings("WeakerAccess")    protected void onCleared() {    }}

主要负责View层与Model层中的逻辑交互

LiveData

  • 定义
var users: MutableLiveData<List<User>> = MutableLiveData()   get() {       if (field.value == null) {           Handler().postDelayed({ loadUsers() }, 3000)       }       return field   }
  • 使用
val model = ViewModelProviders.of(this).get(MyViewModel::class.java)model.users.observe(this, Observer { users ->    if (users != null && users.isNotEmpty()) {        tv1.text = users[0].name    }})

更新数据

users.value = list

Room

  • Entity
@Entity(tableName = "stories")class Story {    @PrimaryKey(autoGenerate = true)    var id = 0    var data = ""    var displayData = ""    var title = ""    override fun toString(): String {        return "Story(id=$id, data='$data', displayData='$displayData', title='$title')"    }}
  • Dao
@Daointerface StoryDao {    @Query("select * from stories")    fun loadAllStories(): LiveData<List<Story>>    @Query("select * from stories")    fun getAllStories(): List<Story>    @Insert(onConflict = OnConflictStrategy.REPLACE)    fun insertStories(list: List<Story>)    @Insert(onConflict = OnConflictStrategy.REPLACE)    fun insertStories(vararg story: Story)    @Query("delete from stories")    fun deleteAllStories(): Int    @Delete    fun deleteStories(vararg story: Story): Int    @Update    fun updateStories(vararg story: Story): Int}
  • Database
@Database(entities = [(Story::class)], version = 1)abstract class AppDatabase : RoomDatabase() {    companion object {        val TAG = "bobby_story_db"    }    abstract fun storyDao(): StoryDao}
  • 使用
object DatabaseManager {    private lateinit var db: AppDatabase    fun initDb(context: Context) {        db = Room.databaseBuilder(context, AppDatabase::class.java, AppDatabase.TAG).build()    }    fun insertStories(stories: List<Story>) {        Thread({            db.beginTransaction()            try {                db.storyDao().insertStories(stories)                db.setTransactionSuccessful()            } finally {                db.endTransaction()            }        }).start()    }    fun insertStory(story: Story) {        Thread({            db.beginTransaction()            try {                db.storyDao().insertStories(story)                db.setTransactionSuccessful()            } finally {                db.endTransaction()            }        }).start()    }    fun deleteAllStories(): Int {        return db.storyDao().deleteAllStories()    }    fun deleteStory() {        Thread({            val stories = getAllStories()            Log.d("delete", stories.toString())            if (stories.isNotEmpty()) {                db.storyDao().deleteStories(stories[0])            }        }).start()    }    fun getAllStories(): List<Story> {        return db.storyDao().getAllStories()    }    fun loadAllStories(): LiveData<List<Story>> {        return db.storyDao().loadAllStories()    }    fun simlutateInsertData() {        val list = ArrayList<Story>()        for (i in 1..20) {            val s = Story()            s.id = (i)            s.data = "bobby-" + i.toString()            s.displayData = "bobby-" + i.toString()            s.title = "bobby-" + i.toString()            list.add(s)        }        insertStories(list)    }}

最后来个效果展示:

这里写图片描述

原创粉丝点击