> 文章列表 > 一.Jetpack全套

一.Jetpack全套

一.Jetpack全套

Jetpack全套

    • 一.Jetpack介绍
      • 1.特性:
      • 2.分类:
    • 二.应用架构
    • 三.LifeCycle:
      • 1.简介
      • 2.简单使用
      • 3.实战:Dialog内存泄漏
    • 四.VideModel
      • 1.介绍
      • 2.简单使用
      • 3.AndroidViewModel使用
      • 4.使用viewmodel实现fragment直接数据共享
    • 五.LiveData
      • 1.介绍
      • 2.常用方法
      • 3.使用场景
      • 4.结合viewModel使用
      • 5.加强练习:
      • 6.结合room使用:后面会用到
    • 五.DataBinding
      • 1.mvvm介绍
      • 2.Data Binding介绍
      • 3.简单使用
      • 4.图片处理
      • 5.其他
        • (1)sub二级标签使用
        • (2)事件监听
        • (3)双向绑定
  • 六.Room数据库
    • 1.介绍
    • 2.优点
    • 3.简单使用CRUD
      • (1)app的gradle配置
      • (2)Student实体类:@Entity
      • (3)StudentDao抽象类:@Dao
      • (4)AppDataBase抽象类:@Database
      • (5)增删改查操作
    • 4.数据库升级

一.Jetpack介绍

一.Jetpack全套
Jetpack是一套库、工具和指南,可以帮助开发者更轻松地编写优质应用。这些组件可以帮助开发者遵循最佳做法、
让开发者摆脱编写样板代码的工作并简化复杂任务,以便开发者将精力集中放在所需的代码上。

1.特性:

  • 加速开发: 组件可以单独采用(不过这些组件是为协同工作而构建的),同时利用Kotlin语言功能帮助开发者提高工作效率。
  • 消除样板代码: Android Jetpack可管理繁琐的Activity(如后台任务、导航和生命周期管理),以便开发者可以专注于如何让自己的应用出类拔萃。
  • 构建高质量的强大应用 Android Jetpack组件围绕现代化设计实践构建而成,具有向后兼容性,可以减少崩溃和内存泄漏。

2.分类:

(1)Architecture(架构组件)可帮助您设计稳健、可测试且易维护的应用

  • Data Binding: 是一种支持库,借助该库,可以以声明方式将可观察数据绑定到界面元素。
  • Lifecycles: 管理Activity 和 Fragment的生命周期,能够帮助开发者轻松的应对Activity/Fragment的生命周期
    变化问题,帮助开发者生成更易于维护的轻量级代码。
  • LiveData: 在底层数据库更改时通知视图,是可观察的数据持有者类。与常规的可观察对象不同,LiveData具
    有生命周期感知功能(例如Activity,Fragment或Service的生命周期)。
  • Navigation: 处理应用内导航所需的一切。
  • Paging: 逐步从您的数据源按需加载信息,帮助开发者一次加载和显示小块数据。按需加载部分数据可减少网
    络带宽和系统资源的使用。
  • Room: 流畅地访问 SQLite 数据库。在SQLite上提供了一个抽象层,以在利用SQLite的全部功能的同时允许更
    健壮的数据库访问。
  • ViewModle: 以注重生命周期的方式管理界面相关的数据。ViewModel类允许数据幸免于配置更改(例如屏幕
    旋转)。通常和DataBinding配合使用,为开发者实现MVVM架构提供了强有力的支持。
  • WorkManager: 管理 Android 的后台作业,即使应用程序退出或设备重新启动,也可以轻松地调度预期将要
    运行的可延迟异步任务。
    (2)Foundation(基础组件)可提供横向功能,例如向后兼容性、测试和 Kotlin 语言支持。
  • Android KTX: 编写更简洁、惯用的 Kotlin 代码,是一组Kotlin扩展程序。优化了供Kotlin使用的Jetpack和
    Android平台API。旨在让开发者利用 Kotlin 语言功能(例如扩展函数/属性、lambda、命名参数和参数默认
    值),以更简洁、更愉悦、更惯用的方式使用 Kotlin 进行 Android 开发。Android KTX 不会向现有的 Android
    API 添加任何新功能。
  • AppCompat: 帮助较低版本的Android系统进行兼容。
  • Auto: 有助于开发 Android Auto 应用的组件。是 Google推出的专为汽车所设计之 Android 功能,旨在取代
    汽车制造商之原生车载系统来执行 Android应用与服务并访问与存取Android手机内容。
  • Benchmark: 从 Android Studio 中快速检测基于 Kotlin 或 Java 的代码。
  • Multidex: 为具有多个 DEX 文件的应用提供支持。
  • Security: 按照安全最佳做法读写加密文件和共享偏好设置。
  • Test: 用于单元和运行时界面测试的 Android 测试框架。
  • TV: 有助于开发 Android TV 应用的组件。
  • Wear OS by Google: 有助于开发 Wear 应用的组件。
    (3)Behavior(行为组件)可帮助您的应用与标准 Android 服务(如通知、权限、分享和 Google 助理)相集成。
  • CameraX: 简化相机应用的开发工作。它提供一致且易于使用的 API 界面,适用于大多数 Android 设备,并可向后兼容至 Android 5.0(API 级别 21)。
  • DownloadManager: 是一项系统服务,可处理长时间运行的HTTP下载。客户端可以请求将URI下载到特定的
    目标文件。下载管理器将在后台进行下载,处理HTTP交互,并在出现故障或在连接更改和系统重新启动后重试下载。
  • Media & playback: 用于媒体播放和路由(包括 Google Cast)的向后兼容 API。 4. Notifications: 提供向后兼容的通知 API,支持 Wear 和 Auto。 5. Permissions: 用于检查和请求应用权限的兼容性 API。 6. Preferences: 创建交互式设置屏幕,建议使用 AndroidX Preference Library 将用户可配置设置集成至应用中。
  • Sharing: 提供适合应用操作栏的共享操作。
  • Slices: 是UI模板,可以通过启用全屏应用程序之外的互动来帮助用户更快地执行任务,即可以创建在应用外
    部显示应用数据的灵活界面。
    (4)UI(界面组件)可提供微件和辅助程序,让您的应用不仅简单易用,还能带来愉悦体验。了解有助于简化界面开发的
    Jetpack Compose。
  • Animation & transitions: 使开发者可以轻松地为两个视图层次结构之间的变化设置动画。该框架通过随时间更改其某些属性值在运行时为视图设置动画。该框架包括用于常见效果的内置动画,并允许开发者创建自定义动画和过渡生命周期回调。
  • Emoji: 使Android设备保持最新的最新emoji表情,开发者的应用程序用户无需等待Android OS更新即可获取最新的表情符号。
  • Fragment: Activity的模块化组成部分。
  • Layout: 定义应用中的界面结构。可以在xml中声明界面元素,也可以在运行时实例化布局元素。
  • Palette: 是一个支持库,可从图像中提取突出的颜色,以帮助开发者创建视觉上引人入胜的应用程序。开发者可以使用调色板库设计布局主题,并将自定义颜色应用于应用程序中的视觉元素。

二.应用架构

一.Jetpack全套

三.LifeCycle:

1.简介

一直以来,解藕都是软件开发永恒的话题。在Android开发中,解藕很大程度上表现为系统组件的生命周期与普通组件之间的解藕,因为普通组件在使用过程中需要依赖系统组件的的生命周期。

举个例子,我们经常需要在页面的onCreate()方法中对组件进行初始化,然后在onStop()中停止组件,或者在onDestory()方法中对进行进行销毁。事实上,这样的工作非常繁琐,会让页面和页面耦合度变高,但又不得不做,因为如果不即时的释放资源,有可能会导致内存泄露。例如,下面是一个在Activity的同生命周期方法中监听调用的例子,代码如下。

public class MyListener {private static final String TAG = "MyListener";public void start(){Log.d(TAG, "start: ");}public void stop(){Log.d(TAG, "stop: ");}public void resume(){Log.d(TAG, "resume: ");}
}
public class LifecycleActivity extends AppCompatActivity {private MyListener mMyListener;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_lifecycle);mMyListener = new MyListener();mMyListener.start();}@Overrideprotected void onDestroy() {super.onDestroy();mMyListener.stop();}
}

虽然,代码看起来没什么问题,但在实际开发中可能会有多个组件在Activity的生命周期中进行回调,这样Activity的生命周期的方法中可能就需要编写大量的代码,这就使得它们难以维护。 我们希望在对组件进行管理不依赖页面的生命周期的回调方法,同时当页面生命周期发生改变时,也能够即时的收到通知。这在Android组件化和架构设计的时候表现的尤为明显。

那纠结什么是Lifecycle组件呢?总的来说,Lifecycle 就是具有生命周期感知能力的组件。简单的理解就是,当Activity/Fragment的生命周期产生变化时,Lifecycle组件会感应相应的生命周期变化,当然我们还可以通过使用Lifecycle组件来在自定义的类中管理Activity/fragment的生命周期。

目前,Lifecycle生命周期组件主要由Lifecycle、LifecycleOwner、LifecycleObserver三个对象构成。
(1)Lifecycle:是一个持有组件生命周期状态与事件(如Activity或Fragment)的信息的类。
(2)LifecycleOwner:Lifecycle的提供者,通过实现LifecycleOwner接口来访问Lifecycle生命周期对象。
Fragment和FragmentActivity类实现了LifecycleOwner接口,它具有访问生命周期的getLifecycle方法,使用时
需要在自己的类中实现LifecycleOwner。
(3)LifecycleObserver:Lifecycle观察者,可以使用LifecycleOwner类的addObserver()方法进行注册,被注册后
LifecycleObserver便可以观察到LifecycleOwner的生命周期事件。

2.简单使用

(1)依赖:

 def lifecycle_version = "2.5.1"implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version")implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version")

(2)按照Lifecycle的使用流程,需要先定义观察者,并重写对应的生命周期:设计模式:观察者模式

public class MyObserver implements LifecycleObserver {private static final String TAG = "MyObserver";@OnLifecycleEvent(Lifecycle.Event.ON_START)public void start(){Log.d(TAG, "start: ");}@OnLifecycleEvent(Lifecycle.Event.ON_STOP)public void stop(){Log.d(TAG, "stop: ");}
}

(3)activity

public class LifecycleActivity2 extends AppCompatActivity {private MyObserver mMyObserver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_lifecycle2);mMyObserver = new MyObserver();getLifecycle().addObserver(mMyObserver);}
}

3.实战:Dialog内存泄漏

当activity关闭的时候,dialog没有关闭,进而导致内存泄漏,下面使用lifecycle打造一个完美的dialog
(1)自定义dialog并实现LifecycleObserver接口

public class MyDiaLog extends Dialog  implements LifecycleObserver {public MyDiaLog(@NonNull Context context) {super(context);}public MyDiaLog(@NonNull Context context, int themeResId) {super(context, themeResId);}protected MyDiaLog(@NonNull Context context, boolean cancelable, @Nullable OnCancelListener cancelListener) {super(context, cancelable, cancelListener);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.layout_dialog);}@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)public void destory(){dismiss();}
}

(2)activity

public class DialogActivity extends AppCompatActivity {private MyDiaLog mMyDiaLog;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_dialog);mMyDiaLog = new MyDiaLog(this);getLifecycle().addObserver(mMyDiaLog);}
}

四.VideModel

1.介绍

ViewModel 同样具有生命周期意识的处理跟UI相关的数据,并且,当设备的一些配置信息改变(例如屏幕旋转)它的数据不会消失。
通常情况下,如果我们不做特殊处理,当屏幕旋转的时候,数据会消失,那 ViewModel 管理的数据为什么不会消失呢,是因为 ViewModel 的生命周期:
一.Jetpack全套注意:不要向ViewModel中传入Context,会导致内存泄漏,如果使用Context请使用AndroidViewModel的Appliction

2.简单使用

案例:当屏幕方向发生改变的时候,数据保持不变

(1)自定义ViewModel

public class NumViewModel extends ViewModel {public int num;
}

(2)activity实现,并旋转屏幕测试

public class ViewModelActivity extends AppCompatActivity {private TextView tv;private  NumViewModel numViewModel;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_view_model);tv = findViewById(R.id.tv);//获得viewmodel,页面切换后数据不变numViewModel = new ViewModelProvider(this).get(NumViewModel.class);tv.setText(numViewModel.num+"");}public void plus(View view) {tv.setText(numViewModel.num+++"");}
}

3.AndroidViewModel使用

public class MyAndriodViewModel extends AndroidViewModel {public int num;public MyAndriodViewModel(@NonNull Application application) {super(application);}
}
public class AndrodiViewModelActivity extends AppCompatActivity {private TextView tv;private MyAndriodViewModel mAndroidViewModel;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_androdi_view_model);tv = findViewById(R.id.tv);mAndroidViewModel = new ViewModelProvider(this).get(MyAndriodViewModel.class);tv.setText(mAndroidViewModel.num);}public void plus(View view) {tv.setText(mAndroidViewModel.num+++"");}
}

4.使用viewmodel实现fragment直接数据共享

public class FragmentViewModel extends ViewModel {public int num;
}
public class OneFragment extends Fragment {private Button bt;private View view;private  FragmentViewModel fragmentViewModel;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {view = inflater.inflate(R.layout.fragment_one, container, false);bt  = view.findViewById(R.id.tv);fragmentViewModel = new ViewModelProvider(getActivity()).get(FragmentViewModel.class);bt.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {fragmentViewModel.num++;bt.setText(fragmentViewModel.num+"");}});return view;}
}
public class TwoFragment extends Fragment {private Button bt;private View view;private  FragmentViewModel fragmentViewModel;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {view = inflater.inflate(R.layout.fragment_two, container, false);bt  = view.findViewById(R.id.tv);fragmentViewModel = new ViewModelProvider(getActivity()).get(FragmentViewModel.class);bt.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {fragmentViewModel.num++;bt.setText(fragmentViewModel.num+"");}});return view;}
}

五.LiveData

在讲 LiveData 之前,我们先看看 LiveData 和 ViewModel 的作用
一.Jetpack全套

1.介绍

从官网的介绍可以看到, LiveData 作用跟RxJava类似,是观察数据的类,相比RxJava,它能够在Activity、Fragment和Service之中正确的处理生命周期。那么 LiveData 有什么优点呢?
- 数据变更的时候更新UI
- 没有内存泄漏
- 不会因为停止Activity崩溃
- 无需手动处理生命周期
- 共享资源

乍看之下 LiveData 挺鸡肋的,事实也确实如此,因为 LiveData 能够实现的功能 RxJava 也可以实现,而且与LiveData 相比, RxJava 拥有着更加丰富的生态,当然,谷歌的官方架构仍然值得我们去学习。

2.常用方法

一.Jetpack全套
一.Jetpack全套

3.使用场景

  • viewModel结合使用:
  • room结合使用:数据库后面讲解

4.结合viewModel使用

(1)自定义ViewModel并定义MutableLiveData变量

public class MyViewModel extends ViewModel {private MutableLiveData<Integer> progress;public MutableLiveData<Integer> getProgress() {if(progress == null){progress = new MutableLiveData<>();progress.setValue(0);}return progress;}
}

(2)activity代码:定时器不断修改数据,liveData观察数据变化并更新UI

public class LiveDataActivity extends AppCompatActivity {private MyViewModel viewModel;private TextView textView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);textView = findViewById(R.id.textView);viewModel = new ViewModelProvider(this).get(MyViewModel.class);textView.setText(String.valueOf(viewModel.getCurrentSecond().getValue()));/*观察数据变化更新UI/viewModel.getCurrentSecond().observe(this, new Observer<Integer>() {@Overridepublic void onChanged(Integer i) {textView.setText(String.valueOf(i));}});startTimer();}private void startTimer() {new Timer().schedule(new TimerTask() {@Overridepublic void run() {//修改数据//非UI线程 postValue//UI线程 setValueviewModel.getCurrentSecond().postValue(viewModel.getCurrentSecond().getValue()+1);}},1000,1000);}
}

5.加强练习:

2个fragment,第二个fragment进度条发生改变,第一个fragment值实时更新
一.Jetpack全套

6.结合room使用:后面会用到

五.DataBinding

1.mvvm介绍

MVVM(全称Model-View-ViewModel)同 MVC 和 MVP 一样,是逻辑分层解偶的模式

2.Data Binding介绍

Data Binding 不算特别新的东西,2015年Google就推出了,但即便是现在,很多人都没有学习过它,我就是这些工程师中的一位,因为我觉得MVP已经足够帮我处理日常的业务, Android Jetpack 的出现,是我研究 Data Binding 的一个契机。
在进行下文之前,我有必要声明一下,MVVM和Data Binding是两个不同的概念,MVVM是一种架构模式,而Data Binding是一个实现数据和UI绑定的框架,是构建MVVM模式的一个工具

3.简单使用

一.Jetpack全套

(1)app gradle配置

android {//....dataBinding {enabled true}}

(2)xml布局,在根标签快捷键选择第一个
一.Jetpack全套
自动生成 databinding 布局文件
一.Jetpack全套
databing标签介绍
一.Jetpack全套
(3)User类:

public class User {private String username;//用户名private int age;//年龄private boolean show;//是否显示private String imageUrl;//图片public User(String username, int age, String imageUrl) {this.username = username;this.age = age;this.imageUrl = imageUrl;}public boolean isShow() {return show;}public void setShow(boolean show) {this.show = show;}public String getImageUrl() {return imageUrl;}public void setImageUrl(String imageUrl) {this.imageUrl = imageUrl;}public User(String username, int age, boolean show, String imageUrl) {this.username = username;this.age = age;this.show = show;this.imageUrl = imageUrl;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public User(String username, int age) {this.username = username;this.age = age;}
}

(4)activity布局

<?xml version="1.0" encoding="utf-8"?>
<layout 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"><data><variablename="user"type="com.bawei.jetpackforjava.databing.User" /><import type="android.view.View"></import></data><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".databing.DataBingActivityOne"><EditTextandroid:text="@{user.username}"android:id="@+id/et_username"android:layout_width="match_parent"android:layout_height="wrap_content"></EditText><EditTextandroid:text='@{user.age+""}'android:id="@+id/et_password"android:layout_width="match_parent"android:layout_height="wrap_content"></EditText><ImageViewandroid:background="@color/black"android:visibility="@{user.show ? View.VISIBLE :View.GONE}"android:id="@+id/iv"android:layout_width="80dp"android:layout_height="80dp"></ImageView><Buttonandroid:id="@+id/bt_login"android:text="修改"android:layout_width="match_parent"android:layout_height="wrap_content"></Button></LinearLayout>
</layout>

(5)activity代码:

public class DataBingActivityOne extends AppCompatActivity {private ActivityDataBingOneBinding mActivityDataBingOneBinding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_data_bing_one);mActivityDataBingOneBinding = DataBindingUtil.setContentView(this,R.layout.activity_data_bing_one);User user = new User("张三", 3,true,"");mActivityDataBingOneBinding.setUser(user);}
}

4.图片处理

思考问题:DataBind中如何显示图片
(1)ImageViewBinderAdapter:图片适配器

public class ImageViewBinderAdapter {//加载网络图片@BindingAdapter("image")public static void setImage(ImageView imageView, String url){if(!TextUtils.isEmpty(url)){Glide.with(imageView.getContext())//这里上下文建议使用application,避免内存泄漏.load(url).placeholder(R.drawable.ic_launcher_background).into(imageView);}else{imageView.setBackgroundColor(Color.GRAY);}}//加载本地图片@BindingAdapter("image")public static void setImage(ImageView imageView, int resId){imageView.setImageResource(resId);}//参数可选,网络图片为空时,加载本地图片@BindingAdapter(value = {"image", "defaultImageResource"}, requireAll = false)public static void setImage(ImageView imageView, String url, int resId){if(!TextUtils.isEmpty(url)){Glide.with(imageView.getContext())这里上下文建议使用application,避免内存泄漏.load(url).placeholder(R.drawable.ic_launcher_background).into(imageView);}else{imageView.setImageResource(resId);}}
}

(2)布局文件中设置image属性引用图片地址

 <ImageViewimage="@{user.imageUrl}"android:background="@color/black"android:visibility="@{user.show ? View.VISIBLE :View.GONE}"android:id="@+id/iv"android:layout_width="80dp"android:layout_height="80dp"></ImageView>

5.其他

(1)sub二级标签使用

(2)事件监听

(3)双向绑定

一.Jetpack全套

六.Room数据库

1.介绍

Room 是一个持久性库,属于 Android Jetpack 的一部分。Room 是 SQLite 数据库之上的一个抽象层。Room 并不直接使用 SQLite,而是负责简化数据库设置和配置以及与数据库交互方面的琐碎工作。此外,Room 还提供 SQLite 语句的编译时检查
一.Jetpack全套
数据实体(Entity)表示应用的数据库中的表。数据实体用于更新表中的行所存储的数据以及创建新行供插入。
数据访问对象 (DAO) 提供应用在数据库中检索、更新、插入和删除数据所用的方法。
数据库类(Database)持有数据库,并且是应用数据库底层连接的主要访问点。数据库类为应用提供与该数据库关联的 DAO 的实例。

2.优点

使用编译时注解,能够对 @Query 和 @Entity 里面的SQL语句等进行验证。
与SQL语句的使用更加贴近,能够降低学习成本。
对 RxJava 2 的支持(大部分都Android数据库框架都支持),对 LiveData 的支持。
@Embedded 能够减少表的创建。

3.简单使用CRUD

(1)app的gradle配置

依赖:

 def room_version = "2.5.0"implementation("androidx.room:room-runtime:$room_version")annotationProcessor("androidx.room:room-compiler:$room_version")// To use Kotlin annotation processing tool (kapt)// To use Kotlin Symbol Processing (KSP)
//    ksp("androidx.room:room-compiler:$room_version")// optional - Kotlin Extensions and Coroutines support for Roomimplementation("androidx.room:room-ktx:$room_version")// optional - RxJava2 support for Roomimplementation("androidx.room:room-rxjava2:$room_version")// optional - Paging 3 Integrationimplementation("androidx.room:room-paging:$room_version")

defaultConfig里面配置:这里注意一定是+=不是= ,后面会介绍

javaCompileOptions {annotationProcessorOptions {//room的数据库概要、记录arguments += ["room.schemaLocation":"$projectDir/schemas".toString()]}}

(2)Student实体类:@Entity

@Entity(tableName = "student")
public class Student {@PrimaryKey(autoGenerate = true)//主键自增@ColumnInfo(name = "id", typeAffinity = ColumnInfo.INTEGER)private long id;@ColumnInfo(name = "username", typeAffinity = ColumnInfo.TEXT)private String username;@ColumnInfo(name = "age", typeAffinity = ColumnInfo.INTEGER)private int age;public Student(long id, String username, int age) {this.id = id;this.username = username;this.age = age;}public long getId() {return id;}public void setId(long id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}

一.Jetpack全套

(3)StudentDao抽象类:@Dao

@Dao
public interface StudentDao {//添加一条数据@Insert(onConflict = OnConflictStrategy.REPLACE)void insert(Student student);//添加多条数据@Insert(onConflict = OnConflictStrategy.REPLACE)void insert(List<Student> students);//删除一条数据@Deletevoid delete(Student student);//删除多条数据@Deletevoid deleteList(List<Student> students);//删除所有数据@Query("delete from Student")void deleteAll();//修改数据@Updatevoid update(Student student);//查询所有@Query("select * from student")List<Student> getAllStudents();//根据姓名查找@Query("select * from student where username =  :username ")List<Student> getStudentByName(String username);
}

(4)AppDataBase抽象类:@Database

/* entities:数据表实体类* version:版本号* exportSchema:是否导出Schema文件*/
@Database(entities = {Student.class},version = 2,exportSchema = true)
public abstract class AppDataBase extends RoomDatabase {public static final String DB_NAME = "StudentDatabase.db";//数据库名称//注意构造不能私有化private static AppDataBase appDataBase;public static AppDataBase getInstance(){if(appDataBase == null){synchronized (AppDataBase.class){appDataBase = Room.databaseBuilder(App.instance,AppDataBase.class,DB_NAME).allowMainThreadQueries()数据库耗时操作,默认不能在主线程执行.build();}}return appDataBase;}private StudentDao studentDao;public abstract StudentDao getStudentDao();
}

(5)增删改查操作

public class RoomActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_room);List<Student> list = new ArrayList<>();Student student1 = new Student(1,"张三1",18);Student student2 = new Student(2,"张三2",28);Student student3 = new Student(3,"张三3",38);Student student4 = new Student(4,"张三4",48);list.add(student1);list.add(student2);list.add(student3);list.add(student4);AppDataBase.getInstance().getStudentDao().insert(list);student2.setUsername("李四");AppDataBase.getInstance().getStudentDao().update(student2);AppDataBase.getInstance().getStudentDao().delete(student2);List<Student> allStudents = AppDataBase.getInstance().getStudentDao().getAllStudents();List<Student> lisi = AppDataBase.getInstance().getStudentDao().getStudentByName("李四");}
}

4.数据库升级

  • 问题:如果用户设备上数据库版本为1,而当前安装的数据库版本为3,怎么办?
  • 解决方案:Room 会判断当前有没有直接1到3的升级方案,如果有,直接执行1到3的升级方案,如果没有,Room就会按照顺序执行Migration(1,2)、Migration(2,3)已完成升级