2026年Android开发笔试题及详细答案_第1页
2026年Android开发笔试题及详细答案_第2页
2026年Android开发笔试题及详细答案_第3页
2026年Android开发笔试题及详细答案_第4页
2026年Android开发笔试题及详细答案_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

2026年Android开发笔试题及详细答案考试时长:120分钟满分:100分适用人群:Android初级/中级开发工程师(校招/社招)说明:本试卷贴合2025-2026年Android开发实际场景,涵盖基础语法、四大组件、Jetpack、性能优化、网络请求、自定义View、跨平台适配等核心知识点,题型全面,答案详细易懂,贴合实际开发场景,无冗余表述。一、单项选择题(每题2分,共20分)下列关于Android四大组件的说法,错误的是()

A.Activity负责界面展示和用户交互,生命周期受系统调度

B.Service可在后台执行耗时任务,8.0后后台启动需使用前台服务

C.BroadcastReceiver可接收系统广播和自定义广播,可执行耗时操作

D.ContentProvider用于跨应用数据共享,对外提供统一访问接口

关于Kotlin协程,下列描述正确的是()

A.协程是线程的一种,启动后会单独占用系统资源

B.withContext(Dispatchers.IO)可将任务切换到IO线程,自动切换回主线程

C.协程的取消是强制性的,一旦调用cancel()就会立即终止任务

D.CoroutineScope的生命周期与宿主组件绑定,宿主销毁时协程会自动取消

下列哪种情况不会导致Android内存泄漏()

A.静态变量持有Activity的Context引用

B.Handler使用静态内部类+WeakReference包装Activity

C.注册BroadcastReceiver后未在Activity销毁时解绑

D.非静态内部类持有外部Activity的引用,且内部类生命周期长于Activity关于JetpackCompose,下列说法错误的是()

A.Compose是声明式UI框架,基于状态驱动更新UI

B.Composable函数可嵌套调用,且可直接在普通函数中调用

C.derivedStateOf可用于防抖,减少不必要的UI重组

D.Recomposer负责触发Composable函数的重组

ANR的全称是ApplicationNotResponding,下列哪种情况不会触发ANR()

A.主线程处理点击事件超过5秒未响应

B.前台BroadcastReceiver执行时间超过10秒

C.后台Service执行时间超过200秒

D.子线程执行网络请求超过30秒

关于Retrofit的说法,正确的是()

A.Retrofit是一个网络请求框架,底层依赖OkHttp实现

B.Retrofit可直接返回实体类,无需手动解析JSON数据

C.@GET注解中只能填写完整的网络请求地址,不能使用占位符

D.Retrofit的请求方法只能在主线程中调用

下列关于Room框架的描述,错误的是()

A.Room是Jetpack中的数据存储框架,封装了SQLite

B.Entity类对应的表名必须与类名一致

C.Dao接口中的方法需添加@Insert、@Query等注解才能生效

D.Room操作数据库不能在主线程中执行,需配合协程或线程池

关于Android布局优化,下列做法错误的是()

A.使用ConstraintLayout减少布局嵌套层级

B.复用布局使用include标签,避免重复编写

C.为ListView的item布局设置固定高度,提升滑动性能

D.尽量使用LinearLayout,避免使用RelativeLayout

下列关于Android权限的说法,正确的是()

A.Android6.0及以上,所有权限都需要动态申请

B.危险权限需要动态申请,普通权限只需在Manifest中声明

C.动态申请权限时,用户拒绝后就无法再次申请

D.权限申请只能在Activity中进行,Fragment中无法申请

关于跨平台适配,下列说法正确的是()

A.KMP(KotlinMultiplatform)的expect/actual关键字可实现跨平台代码复用

B.ArkTS的@Provide/@Consume与KMP的expect/actual功能完全一致

C.跨平台框架开发的应用,性能一定优于原生开发

D.HarmonyOSNEXT应用可直接运行Android原生应用,无需适配

二、多项选择题(每题3分,共15分,多选、少选、错选均不得分)Android中常见的异步通信方式有()

A.Handler+Message

B.Kotlin协程

C.AsyncTask(已废弃)

D.WorkManager

关于Activity的启动模式,下列说法正确的有()

A.standard模式:每次启动都会创建一个新的Activity实例

B.singleTop模式:若Activity在栈顶,再次启动不会创建新实例

C.singleTask模式:整个栈中只会有一个该Activity实例,启动时会清空栈顶以上的实例

D.singleInstance模式:该Activity会单独占用一个任务栈,且栈中只有这一个实例

Android性能优化的核心方向包括()

A.内存优化:避免内存泄漏、减少OOM

B.布局优化:减少渲染耗时、降低布局嵌套

C.启动优化:减少启动时间、优化启动流程

D.网络优化:减少请求次数、压缩请求数据

下列关于Jetpack组件的说法,正确的有()

A.ViewModel用于存储UI相关数据,生命周期与Activity/Fragment无关

B.LiveData可实现UI与数据源的解耦,数据变化时自动更新UI

C.Navigation用于统一管理Activity/Fragment的跳转逻辑

D.WorkManager用于处理可延迟、可调度的后台任务,支持设备重启后继续执行

关于自定义View的开发,下列说法正确的有()

A.自定义View需重写onMeasure()、onLayout()、onDraw()三个核心方法

B.onMeasure()用于测量View的宽高,onLayout()用于确定View在父容器中的位置

C.onDraw()用于绘制View的内容,可使用Canvas和Paint进行绘制

D.自定义View的触摸事件处理需重写onTouchEvent()方法

三、判断题(每题1分,共10分,对的打√,错的打×)Activity的onPause()方法调用后,界面一定不可见。()Service是运行在后台的组件,一定不会占用主线程资源。()Kotlin的空安全机制可避免空指针异常,所有变量都不能为null。()Retrofit的@POST注解用于发送GET请求,@GET注解用于发送POST请求。()Room框架中,@Query注解中的SQL语句会在编译时进行语法检查。()Compose的状态变量必须使用remember修饰,否则状态变化不会触发UI重组。()Android8.0以后,静态注册的隐式广播大部分被禁止,只能使用动态注册。()内存泄漏会导致应用内存占用不断增加,最终引发OOM。()ConstraintLayout可以实现LinearLayout和RelativeLayout的所有功能,且性能更优。()WorkManager可以替代Service,处理所有后台任务。()四、填空题(每题2分,共10分)Android中,________是线程的消息循环器,负责循环取出MessageQueue中的消息并分发。JetpackCompose中,________用于将数据流转换为可观察的状态,当数据流变化时自动更新UI。Android中,图片加载框架Glide的核心功能是________、________和内存缓存。Room框架中,________用于定义数据访问接口,包含插入、查询、更新、删除等方法。Android应用的启动分为________和________,其中后者启动速度更快,因为无需重新创建进程和Application。五、简答题(每题5分,共20分)简述Android四大组件的作用及生命周期核心要点(每个组件简要说明作用,重点说明Activity的生命周期)。简述ViewModel和LiveData的关系及使用场景,为什么能避免内存泄漏?Android中常见的内存泄漏场景有哪些?请列举至少3种,并说明对应的解决方案。简述Retrofit的工作原理,以及如何使用Retrofit实现一个GET请求(简要说明步骤和核心代码)。六、编程题(每题12.5分,共25分)使用Kotlin语言,实现一个简单的登录页面逻辑:

要求:

1.布局包含两个EditText(用户名、密码)和一个Button(登录);

2.点击登录按钮时,校验用户名和密码(用户名不为空、密码长度≥6);

3.校验通过,使用Toast提示“登录成功”;校验失败,提示对应错误信息(如“用户名不能为空”“密码长度不足6位”);

4.避免EditText输入时的软键盘遮挡问题;

5.给出完整的布局XML代码和Activity代码。

使用Room框架实现本地数据存储,要求:

1.定义一个User实体类(包含id、username、password、createTime四个字段);

2.定义UserDao接口,包含插入(insert)、查询所有(queryAll)、根据id删除(deleteById)三个方法;

3.定义AppDatabase类,继承RoomDatabase,关联User实体和UserDao;

4.在Activity中,使用Coroutines执行数据库操作(避免主线程阻塞),实现插入一条用户数据,并查询所有用户数据,打印到日志;

5.给出完整的实体类、Dao接口、数据库类和Activity核心代码。

参考答案及详细解析一、单项选择题(每题2分,共20分)答案:C

解析:BroadcastReceiver的核心作用是接收和处理广播消息,**不能执行耗时操作**(超过10秒会触发ANR),耗时操作需交给子线程或Service处理。A、B、D选项描述均正确。

答案:D

解析:A错误,协程不是线程,是运行在线程上的轻量级任务,不单独占用系统资源;B错误,withContext(Dispatchers.IO)仅将任务切换到IO线程,不会自动切换回主线程,需在协程作用域中配合使用;C错误,协程的取消是协作式的,需在任务中检查isActive状态,否则不会立即终止;D正确,CoroutineScope(如lifecycleScope)与宿主组件(Activity/Fragment)生命周期绑定,宿主销毁时协程会自动取消,避免内存泄漏。

答案:B

解析:A、C、D均会导致内存泄漏:A中静态变量生命周期与App一致,持有Activity引用会导致Activity无法被GC回收;C中未解绑广播接收器,接收器持有Activity引用;D中非静态内部类默认持有外部Activity引用,若内部类生命周期更长,会导致Activity泄漏。B是避免Handler内存泄漏的标准写法,静态内部类不持有外部Activity引用,WeakReference不会阻止Activity被GC回收,因此不会导致泄漏。

答案:B

解析:A、C、D描述均正确;B错误,Composable函数只能在其他Composable函数中调用,不能直接在普通函数中调用,因为Composable函数依赖Compose的运行环境(Recomposer)。

答案:D

解析:ANR是主线程阻塞导致的,A、B、C均是触发ANR的常见场景;D中子线程执行耗时操作,不会阻塞主线程,因此不会触发ANR。

答案:A

解析:A正确,Retrofit是基于OkHttp封装的网络请求框架,简化了网络请求的编写;B错误,Retrofit需配合Gson等解析器,才能将响应数据解析为实体类,不能直接返回实体类;C错误,@GET注解中可使用占位符(如@GET("user/{id}")),通过@Path注解传递参数;D错误,Retrofit的请求方法默认在子线程中执行,无需手动切换线程。答案:B

解析:A、C、D描述均正确;B错误,Entity类对应的表名可通过@Entity(tableName="xxx")注解指定,无需与类名一致。答案:D

解析:A、B、C均是布局优化的正确做法;D错误,LinearLayout和RelativeLayout的选择需根据布局需求,复杂布局中ConstraintLayout性能更优,LinearLayout适用于简单的线性布局,不能一概而论“尽量使用LinearLayout”。

答案:B

解析:A错误,Android6.0及以上,只有危险权限需要动态申请,普通权限只需在Manifest中声明即可;B正确,危险权限(如相机、存储、定位)需动态申请,普通权限(如网络、蓝牙)无需动态申请;C错误,用户拒绝权限后,可通过shouldShowRequestPermissionRationale()提示用户开启权限,再次申请;D错误,Fragment中可通过requestPermissions()方法申请权限,与Activity中用法一致。

答案:A

解析:A正确,KMP的expect/actual关键字可实现跨平台代码复用,expect定义接口,actual在不同平台(Android、iOS等)实现具体逻辑;B错误,ArkTS的@Provide/@Consume用于组件间状态传递,KMP的expect/actual用于跨平台代码实现,功能不同;C错误,跨平台框架开发的应用,性能通常略低于原生开发,尤其是复杂UI场景;D错误,HarmonyOSNEXT不支持直接运行Android原生应用,需进行适配改造。

二、多项选择题(每题3分,共15分)答案:ABD

解析:A、B、D均是Android中常见的异步通信方式;C错误,AsyncTask已在Android11中废弃,不推荐使用,推荐使用协程或线程池替代。

答案:ABCD

解析:四个选项均是Activity启动模式的正确描述,standard(默认模式,每次创建新实例)、singleTop(栈顶复用)、singleTask(栈内唯一,清空栈顶)、singleInstance(单独任务栈,唯一实例),符合实际开发中的使用场景。

答案:ABCD

解析:Android性能优化的核心方向包括内存优化、布局优化、启动优化、网络优化,此外还有动画优化、功耗优化等,四个选项均正确。

答案:BCD

解析:A错误,ViewModel的生命周期与Activity/Fragment的生命周期相关,当Activity/Fragment销毁时,ViewModel才会被销毁(屏幕旋转时不会销毁);B、C、D描述均正确,LiveData实现UI与数据源解耦,Navigation统一跳转逻辑,WorkManager处理后台任务并支持设备重启后续执行。

答案:BCD

解析:A错误,自定义View不一定需要重写所有三个方法:若只需自定义绘制,重写onDraw()即可;若需自定义宽高,重写onMeasure();若需自定义布局位置,重写onLayout()(通常自定义ViewGroup时需要);B、C、D描述均正确。

三、判断题(每题1分,共10分)答案:×

解析:onPause()方法调用后,界面可能仍然可见(如启动一个透明主题的Activity),只有onStop()方法调用后,界面才完全不可见。

答案:×

解析:Service默认运行在主线程中,若在Service中执行耗时操作,会阻塞主线程,导致ANR,因此耗时操作需在Service中开启子线程执行。

答案:×

解析:Kotlin的空安全机制通过可空类型(加?)和非空类型区分,可空类型变量可以为null,非空类型变量不能为null,目的是避免空指针异常,而非禁止所有变量为null。答案:×

解析:Retrofit中,@GET注解用于发送GET请求,@POST注解用于发送POST请求,二者不能混淆。

答案:√

解析:Room框架会在编译时检查@Query注解中的SQL语句语法,若语法错误,会直接编译失败,避免运行时SQL错误。

答案:√

解析:Compose的状态变量必须使用remember修饰,remember会保存状态值,当状态变化时,会触发依赖该状态的Composable函数重组,否则状态变化不会影响UI。

答案:√

解析:Android8.0(API26)以后,系统禁止大部分静态注册的隐式广播,目的是优化系统性能,减少后台耗电,如需接收隐式广播,需使用动态注册。

答案:√

解析:内存泄漏会导致无用对象无法被GC回收,应用内存占用不断增加,当内存占用超过系统分配的上限时,会引发OOM(OutOfMemoryError)。

答案:√

解析:ConstraintLayout是Google推荐的布局方式,可实现LinearLayout(线性布局)和RelativeLayout(相对布局)的所有功能,且能有效减少布局嵌套层级,提升渲染性能。

答案:×

解析:WorkManager适用于处理可延迟、可调度、非即时的后台任务(如定期同步数据),但不能替代Service,对于需要长期运行、即时响应的后台任务(如音乐播放),仍需使用Service。

四、填空题(每题2分,共10分)答案:Looper

解析:Looper是线程的消息循环器,每个线程最多有一个Looper,主线程默认已创建Looper,子线程需手动调用Looper.prepare()创建。

答案:Flow(或StateFlow、SharedFlow)

解析:Flow是Jetpack中用于处理数据流的组件,可将数据流转换为可观察的状态,StateFlow和SharedFlow是Flow的子类,适用于UI状态管理,当数据流变化时自动更新UI。

答案:图片加载、图片压缩

解析:Glide的核心功能包括图片加载(从网络、本地、资源文件加载图片)、图片压缩(根据控件大小压缩图片,减少内存占用)、内存缓存和磁盘缓存(提升加载速度)。

答案:Dao(或数据访问对象)

解析:Room框架中,Dao(DataAccessObject)接口用于定义数据访问方法,通过@Insert、@Query、@Update、@Delete等注解指定具体操作,Room会自动生成实现类。

答案:冷启动、热启动

解析:冷启动是指应用首次启动,需要创建进程、初始化Application、启动Activity,耗时较长;热启动是指应用已在后台运行,再次启动时无需重新创建进程和Application,直接启动Activity,速度更快。

五、简答题(每题5分,共20分)答案:

1.四大组件作用:

-Activity:页面载体,负责界面展示和用户交互,是应用与用户交互的主要入口。

-Service:后台服务,无界面,负责在后台执行耗时任务(如音乐播放、数据同步),不受页面生命周期影响。

-BroadcastReceiver:广播接收器,用于接收系统广播(如网络变化、开机完成)或自定义广播,实现跨组件通信。

-ContentProvider:数据共享组件,用于跨应用共享数据(如系统通讯录、媒体库),对外提供统一的访问接口。

2.Activity生命周期核心要点(7个核心方法):

-onCreate():Activity创建时调用,用于初始化界面(setContentView)、绑定控件、初始化数据,仅调用一次。

-onStart():Activity即将可见时调用,此时界面还未与用户交互。

-onResume():Activity进入前台,可与用户交互,此时Activity处于运行状态。

-onPause():Activity失去焦点(如启动新Activity)时调用,用于保存轻量数据,此时界面可能仍可见,不能执行耗时操作。

-onStop():Activity完全不可见时调用,用于释放非必要资源。

-onRestart():Activity从停止状态重新启动时调用,之后会执行onStart()。

-onDestroy():Activity被销毁前调用,用于释放所有资源(如解绑广播、取消网络请求),仅调用一次。

补充:页面跳转时生命周期顺序(A→B):A.onPause()→B.onCreate()→B.onStart()→B.onResume()→A.onStop();若A被回收,返回时会重新执行A的onCreate()。

答案:

1.关系:ViewModel与LiveData是配套使用的,ViewModel用于存储UI相关数据,隔离UI与业务逻辑;LiveData是可观察的数据持有者,用于将ViewModel中的数据暴露给UI,实现数据与UI的解耦。

2.使用场景:适用于MVVM架构,用于管理页面数据(如列表数据、表单数据),解决屏幕旋转时数据丢失的问题,同时避免内存泄漏。

3.避免内存泄漏的原因:

-ViewModel的生命周期与Activity/Fragment的生命周期解绑,屏幕旋转时Activity/Fragment销毁重建,但ViewModel不会被销毁,避免因页面重建导致的数据重复请求和内存泄漏。

-LiveData会自动感知宿主(Activity/Fragment)的生命周期,当宿主处于销毁状态时,LiveData会自动移除观察者,不会持有宿主的引用,因此不会导致内存泄漏。

答案:

常见内存泄漏场景及解决方案(至少3种):

1.场景1:静态变量持有Activity/Fragment的Context引用

-原因:静态变量生命周期与App一致,若持有Activity引用,会导致Activity销毁后无法被GC回收。

-解决方案:尽量使用ApplicationContext(生命周期与App一致,不会导致Activity泄漏);若必须使用ActivityContext,使用WeakReference包装,避免强引用。

2.场景2:Handler内存泄漏

-原因:非静态内部类/匿名内部类的Handler持有外部Activity引用,若MessageQueue中还有未处理的Message,会导致Activity无法被GC回收。

-解决方案:将Handler定义为静态内部类,并用WeakReference包装Activity;在Activity销毁时,调用handler.removeCallbacksAndMessages(null),清空所有未处理的消息。

3.场景3:注册广播/监听器后未解绑

-原因:动态注册的BroadcastReceiver、EventBus监听器等,若在Activity销毁时未解绑,会持有Activity引用,导致泄漏。

-解决方案:在Activity的onDestroy()方法中,调用unregisterReceiver()解绑广播,调用EventBus.unregister()解绑监听器。

4.补充场景:非静态内部类持有外部Activity引用(如自定义线程、回调)

-解决方案:将内部类改为静态内部类;若需要访问外部Activity的资源,用WeakReference包装Activity。

答案:

1.Retrofit工作原理:

Retrofit是基于OkHttp封装的网络请求框架,核心是通过动态代理生成网络请求接口的实现类,将接口中的注解(如@GET、@POST)解析为OkHttp的Request对象,发起网络请求,再将响应数据解析为指定的实体类,返回给调用者。

核心流程:①创建Retrofit实例,配置BaseUrl、数据解析器(如Gson);②定义网络请求接口,用注解指定请求方式、路径、参数;③通过Retrofit.create()生成接口实现类;④调用接口方法,发起网络请求,获取响应数据。

2.使用Retrofit实现GET请求的步骤及核心代码:

步骤1:添加依赖(build.gradle)

步骤2:定义实体类(对应响应数据)

步骤3:定义网络请求接口

步骤4:创建Retrofit实例,发起请求

核心代码:

//1.实体类(User)

dataclassUser(valid:Int,valusername:String,valage:Int)

//2.网络请求接口

interfaceApiService{

//GET请求,路径为user,参数为id,通过@Query传递

@GET("user")

suspendfungetUser(@Query("id")id:Int):Response<User>

}

//3.创建Retrofit实例,发起请求(在Activity/Fragment的协程中调用)

valretrofit=Retrofit.Builder()

.baseUrl("/")//替换为实际BaseUrl

.addConverterFactory(GsonConverterFactory.create())//Gson解析

.build()

valapiService=retrofit.create(ApiService::class.java)

//发起请求

lifecycleScope.launch{

valresponse=apiService.getUser(1)

if(response.isSuccessful){

valuser=response.body()//获取响应实体类

//处理数据

}else{

//处理请求失败

}

}

六、编程题(每题12.5分,共25分)答案:

1.布局XML代码(activity_login.xml):

<?xmlversion="1.0"encoding="utf-8"?>

<LinearLayoutxmlns:android="/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

android:padding="20dp"

android:fitsSystemWindows="true"><!--避免软键盘遮挡-->

<EditText

android:id="@+id/et_username"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:hint="请输入用户名"

android:inputType="text"

android:layout_marginBottom="15dp"/>

<EditText

android:id="@+id/et_password"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:hint="请输入密码"

android:inputType="textPassword"

android:layout_marginBottom="20dp"/>

<Button

android:id="@+id/btn_login"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="登录"

android:backgroundTint="@color/colorPrimary"/>

</LinearLayout>

2.Activity代码(LoginActivity.kt):

classLoginActivity:AppCompatActivity(){

//绑定控件

privatelateinitvaretUsername:EditText

privatelateinitvaretPassword:EditText

privatelateinitvarbtnLogin:Button

overridefunonCreate(savedInstanceState:Bundle?){

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_login)

//初始化控件

initView()

//设置登录按钮点击事件

setLoginClick()

}

privatefuninitView(){

etUsername=findViewById(R.id.et_username)

etPassword=findViewById(R.id.et_password)

btnLogin=findViewById(R.id.btn_login)

//解决软键盘遮挡问题:设置Activity的windowSoftInputMode(也可在Manifest中配置)

window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)

}

privatefunsetLoginClick(){

btnLogin.setOnClickListener{

//获取输入的用户名和密码

valusername=etUsername.text.toString().trim()

valpassword=etPassword.text.toString().trim()

//校验输入

when{

username.isEmpty()->{

Toast.makeText(this,"用户名不能为空",Toast.LENGTH_SHORT).show()

}

password.length<6->{

Toast.makeText(this,"密码长度不足6位",Toast.LENGTH_SHORT).show()

}

else->{

//校验通过,提示登录成功(实际开发中需发起网络请求)

Toast.makeText(this,"登录成功",Toast.LENGTH_SHORT).show()

//跳转至首页(可选)

startActivity(Intent(this,MainActivity::class.java))

finish()

}

}

}

}

}

补充说明:fitsSystemWindows="true"和windowSoftInputMode(SOFT_INPUT_ADJUST_PAN)共同作用,避免软键盘遮挡输入框;trim()方法用于去除输入内容的前后空格,避免空格导致的校验错误。

答案:

1.实体类(User.kt):

importandroidx.room.Entity

importandroidx.room.PrimaryKey

importjava.util.Date

//定义实体类,对应数据库中的user表

@Entity(tableName="user")

dataclassUser(

@PrimaryKey(autoGenerate=true)//主键自增

valid:Int=0,

valusername:String,

valpassword:String,

valcreateTime:Date=Date()//创建时间,默认当前时间

)

2.Dao接口(UserDao.kt):

importandroidx.room.Dao

importandroidx.room.Delete

importandroidx.room.Insert

importandroidx.room.Query

importkotlinx.coroutines.flow.Flow

@Dao

interfaceUserDao{

//插入一条用户数据

@Insert

suspendfuninsertUser(user:User)

//查询所有用户数据,返回Flow,数据变化时自动通知

@Query("SELECT*FROMuserORDERBYcreateTimeDESC")

suspendfunqueryAllUsers():List<User>

//根据id删除用户数据

@Delete

suspendfundeleteUserById(user:User)//也可通过@Query("DELETEFROMuserWHEREid=:id")实现

}

3.数据库类(AppDatabase.kt):

importandroidx.room.Database

importandroidx.room.Room

importandroidx.room.RoomDatabase

importandroid.content.Context

//数据库版本号,升级时需修改

@Database(entities=[User::class],version=1,exportSchema=false)

abstractclassAppDatabase:RoomDatabase(){

//提供Dao接口的实例

abstractfunuserDao():UserDao

companionobject{

//单例模式,避免创建多个数据库实例

privatevarinstance:AppDatabase?=null

fungetInstance(context:Context):AppDatabase{

if(instance==null){

instance=Room.databaseBuilder(

context.applicationContext,//使用ApplicationContext,避免内存泄漏

AppDatabase::class.java,

"app_database"//数据库名称

).build()

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论