期末速成 移动应用开发开发(安卓)
文章目录

Android 开发期末速成重点知识总结
第1章 开始启程,你的第一行Android代码
重点知识
- 应用软件:用户可使用的程序设计语言及应用程序的集合,分为应用软件包和用户程序。
- 移动应用:面向个人(To C)或企业(To B),联网方式包括单机、局域网、互联网。
- 常见操作系统:Windows、Linux(CentOS、Ubuntu)、ChromeOS、iOS/iPadOS、Android、HarmonyOS。
- Android系统特点:
- 开放性(开源)
- 平等性
- 无界性
- 硬件丰富
- Android系统架构:
- Linux内核层:提供硬件驱动支持。
- 系统运行库层:提供主要特性支持,如SQLite、OpenGL|ES、Webkit。
- 应用框架层:提供构建应用程序的API。
- 应用层:所有安装在手机上的应用程序。
- Android主要系统版本:查看Android系统版本市占率。
- Android应用开发特色:
- 四大组件:Activity、Service、BroadcastReceiver、ContentProvider。
- 丰富的系统控件。
- SQLite数据库。
- 强大的多媒体支持。
- 支持机器学习模型部署。
- 开发环境搭建:
- 使用Android Studio集成工具。
- 下载地址:https://developer.android.google.cn/studio。
- 创建HelloWorld项目:
- 选择Empty Views Activity。
- 配置项目名称、包名、语言(Kotlin)、最低API级别。
- 项目结构:
app:代码和资源目录。build.gradle:项目构建脚本。settings.gradle:模块引入配置。AndroidManifest.xml:应用配置文件。
- 日志工具:
Log.v():打印琐碎信息。Log.d():打印调试信息。Log.i():打印重要数据。Log.w():打印警告信息。Log.e():打印错误信息。
课后习题
单选题
-
Android系统是基于以下哪种内核构建的?答案:B
- A. Windows
- B. Linux
- C. macOS
- D. ChromeOS
-
Android应用开发中,以下哪种语言被推荐用于开发?答案:B
- A. Java
- B. Kotlin
- C. Swift
- D. Python
-
在Android Studio中创建项目时,以下哪个选项用于指定项目代码存放的位置?答案:C
- A. Name
- B. Package name
- C. Save location
- D. Language
-
Android系统架构中,提供硬件驱动支持的是哪一层?答案:A
- A. Linux内核层
- B. 系统运行库层
- C. 应用框架层
- D. 应用层
-
Android应用开发的四大组件不包括以下哪一项?答案:E
- A. Activity
- B. Service
- C. BroadcastReceiver
- D. ContentProvider
- E. Fragment
-
在Android开发中,用于显示日志信息的方法是?答案:D
- A.
println() - B.
print() - C.
showLog() - D.
Log.d()
- A.
-
Android系统的主要特点是?答案:A
- A. 开放性
- B. 封闭性
- C. 单一性
- D. 专有性
-
在Android开发中,用于定义应用配置的文件是?答案:D
- A.
build.gradle - B.
settings.gradle - C.
AndroidManifest.xml - D.
AndroidManifest.xml
- A.
-
在Android开发中,用于构建项目的文件是?答案:A
- A.
build.gradle - B.
settings.gradle - C.
AndroidManifest.xml - D.
app
- A.
-
在Android开发中,用于管理模块引入的文件是?答案:B
- A.
build.gradle - B.
settings.gradle - C.
AndroidManifest.xml - D.
app
- A.
-
在Android开发中,用于存储日志信息的方法是?答案:E
- A.
Log.v() - B.
Log.d() - C.
Log.i() - D.
Log.w() - E.
Log.e()
- A.
-
在Android开发中,用于显示错误信息的方法是?答案:E
- A.
Log.v() - B.
Log.d() - C.
Log.i() - D.
Log.w() - E.
Log.e()
- A.
-
在Android开发中,用于显示警告信息的方法是?答案:D
- A.
Log.v() - B.
Log.d() - C.
Log.i() - D.
Log.w() - E.
Log.e()
- A.
-
在Android开发中,用于显示重要信息的方法是?答案:C
- A.
Log.v() - B.
Log.d() - C.
Log.i() - D.
Log.w() - E.
Log.e()
- A.
-
在Android开发中,用于显示调试信息的方法是?答案:B
- A.
Log.v() - B.
Log.d() - C.
Log.i() - D.
Log.w() - E.
Log.e()
- A.
多选题
-
Android系统架构包括以下哪些层次?答案:A, B, C, D
- A. Linux内核层
- B. 系统运行库层
- C. 应用框架层
- D. 应用层
- E. 数据库层
-
Android应用开发中,以下哪些是Android的四大组件?答案:A, B, C, D
- A. Activity
- B. Service
- C. BroadcastReceiver
- D. ContentProvider
- E. Fragment
-
在Android开发中,以下哪些方法用于日志记录?答案:A, B, C, D, E
- A.
Log.v() - B.
Log.d() - C.
Log.i() - D.
Log.w() - E.
Log.e()
- A.
-
在Android开发中,以下哪些是常见的操作系统?答案:A, B, C, D, E
- A. Windows
- B. Linux
- C. ChromeOS
- D. iOS/iPadOS
- E. Android
-
在Android开发中,以下哪些是Android应用开发的特色?答案:A, B, C, D
- A. 四大组件
- B. 丰富的系统控件
- C. SQLite数据库
- D. 强大的多媒体支持
- E. 高性能计算
简答题
-
简述Android系统的开放性特点及其优势。
- 答案:Android系统的开放性特点在于其开源性,允许开发者自由访问和修改源代码。这使得开发者可以定制系统功能,优化性能,增加新特性,从而提升用户体验。同时,开放性也促进了开发者社区的活跃,加速了技术的创新和发展。
-
请列举Android应用开发的四大组件,并简述它们的作用。
- 答案:
- Activity:用于创建用户界面和处理用户交互。
- Service:用于在后台执行长时间运行的任务,不提供用户界面。
- BroadcastReceiver:用于监听和响应系统或应用发出的广播消息。
- ContentProvider:用于跨应用共享数据,提供数据访问接口。
- 答案:
-
简述Android开发环境的搭建步骤。
- 答案:
- 下载并安装Android Studio。
- 配置SDK路径。
- 创建一个新的Android项目,选择项目类型、名称、包名、保存位置、语言和最低API级别。
- 点击“Finish”完成项目创建。
- 答案:
综合题
- 创建一个简单的Android项目,项目名称为
MyFirstApp,包名为com.example.myfirstapp,保存位置为C:\AndroidProjects,使用Kotlin语言,最低API级别为API 21。请写出创建项目的步骤,并说明项目创建完成后,app目录下包含哪些主要文件及其作用。- 答案:
- 步骤:
- 打开Android Studio,选择“Start a new Android Studio project”。
- 选择“Empty Activity”,点击“Next”。
- 在“Configure your new project”页面,填写项目名称
MyFirstApp,包名com.example.myfirstapp,保存位置C:\AndroidProjects,选择语言Kotlin,最低API级别API 21。 - 点击“Finish”完成项目创建。
app目录下主要文件及其作用:AndroidManifest.xml:定义应用的基本信息,包括活动、服务、广播接收器等组件的配置。build.gradle:定义项目的构建配置,包括依赖项、插件等。res目录:存储应用的资源,如布局文件、图片、字符串等。src目录:存储应用的源代码,包括活动、服务等组件的实现。assets目录:存储原始资源文件,如HTML、CSS、JavaScript等。libs目录:存储应用的依赖库文件。
- 步骤:
- 答案:
第2章 探究新语言,快速入门Kotlin编程
重点知识
- Kotlin发展历程:
- 2011年发布第一个版本,2012年开源。
- 2016年发布1.0正式版。
- 2017年成为Android开发一级语言。
- 2019年宣布Kotlin First。
- Kotlin优势:
- 语法简洁,代码量少。
- 语法高级,支持现代特性。
- 语言安全,杜绝空指针异常。
- 与Java完全兼容。
- Kotlin工作原理:
- Kotlin代码编译成class文件,与Java虚拟机兼容。
- 变量和函数:
- 变量:
val:不可变变量。var:可变变量。
- 函数:
- 使用
fun关键字定义。 - 可以省略返回值类型。
- 单行函数语法糖。
- 示例:
简化为:fun add(a: Int, b: Int): Int { return a + b }fun add(a: Int, b: Int) = a + b
- 使用
- 变量:
- 逻辑控制:
- if语句:可以有返回值。
val max = if (a > b) a else b - when语句:替代if语句,支持多种匹配方式。
when (x) { 1 -> println("x == 1") 2 -> println("x == 2") else -> println("x is neither 1 nor 2") } - for-in循环:遍历区间或集合。
for (i in 1..10) { println(i) }
- if语句:可以有返回值。
- 面向对象编程:
- 类与对象:
class Person { var name: String = "" var age: Int = 0 fun eat() { println("$name is eating. He is $age years old.") } } - 继承:
open class Person { var name: String = "" var age: Int = 0 } class Student : Person() { var sno: String = "" var grade: Int = 0 } - 接口:
interface Study { fun readBooks() fun doHomework() } - 数据类:
data class Cellphone(val brand: String, val price: Double) - 单例类:
object Singleton { fun singletonTest() { println("singletonTest is called.") } }
- 类与对象:
- Lambda表达式:
- 一小段可以作为参数传递的代码。
- 示例:
val list = listOf("Apple", "Banana", "Orange") val newList = list.map { it.toUpperCase() }
- 空指针检查:
- 可空类型系统:
Int?表示可为空的整型。 - 判空辅助工具:
?.:安全调用。?::Elvis运算符。let:延迟初始化。
val a: String? = "Kotlin" val length = a?.length ?: 0
- 可空类型系统:
课后习题
单选题
-
Kotlin语言是在哪一年发布的第一个版本?答案:A
- A. 2011
- B. 2012
- C. 2016
- D. 2017
-
在Kotlin中,
val关键字用于声明什么类型的变量?答案:B- A. 可变变量
- B. 不可变变量
- C. 局部变量
- D. 全局变量
-
Kotlin中,
fun关键字用于定义什么?答案:C- A. 类
- B. 接口
- C. 函数
- D. 对象
-
Kotlin中,
when语句的作用是什么?答案:D- A. 循环
- B. 条件判断
- C. 数据转换
- D. 多分支选择
-
在Kotlin中,
var关键字用于声明什么类型的变量?答案:A- A. 可变变量
- B. 不可变变量
- C. 局部变量
- D. 全局变量
-
Kotlin中,
fun关键字后面可以省略的是?答案:B- A. 参数列表
- B. 返回值类型
- C. 函数体
- D. 函数名
-
在Kotlin中,
when语句可以替代什么语句?答案:B- A.
for - B.
if - C.
while - D.
do...while
- A.
-
在Kotlin中,
for-in循环用于遍历什么?答案:D- A. 数组
- B. 集合
- C. 字符串
- D. 区间
-
在Kotlin中,
val和var的区别是什么?答案:B- A.
val用于声明局部变量,var用于声明全局变量 - B.
val用于声明不可变变量,var用于声明可变变量 - C.
val用于声明全局变量,var用于声明局部变量 - D.
val用于声明可变变量,var用于声明不可变变量
- A.
-
在Kotlin中,
fun关键字后面可以省略的是?答案:B- A. 参数列表
- B. 返回值类型
- C. 函数体
- D. 函数名
-
在Kotlin中,
when语句可以替代什么语句?答案:B- A.
for - B.
if - C.
while - D.
do...while
- A.
-
在Kotlin中,
for-in循环用于遍历什么?答案:D- A. 数组
- B. 集合
- C. 字符串
- D. 区间
-
在Kotlin中,
val和var的区别是什么?答案:B- A.
val用于声明局部变量,var用于声明全局变量 - B.
val用于声明不可变变量,var用于声明可变变量 - C.
val用于声明全局变量,var用于声明局部变量 - D.
val用于声明可变变量,var用于声明不可变变量
- A.
-
在Kotlin中,
fun关键字后面可以省略的是?答案:B- A. 参数列表
- B. 返回值类型
- C. 函数体
- D. 函数名
-
在Kotlin中,
when语句可以替代什么语句?答案:B- A.
for - B.
if - C.
while - D.
do...while
- A.
多选题
-
Kotlin相比于Java的优势包括以下哪些?答案:A, B, C, D
- A. 语法简洁
- B. 语法高级
- C. 语言安全
- D. 与Java完全兼容
- E. 更快的运行速度
-
Kotlin中,以下哪些是逻辑控制语句?答案:A, B, C, D
- A.
if - B.
when - C.
for-in - D.
while - E.
switch
- A.
-
在Kotlin中,以下哪些是面向对象编程的特性?答案:A, B, C, D
- A. 类与对象
- B. 继承
- C. 接口
- D. 数据类
- E. 单例类
-
在Kotlin中,以下哪些是空指针检查的工具?答案:A, B, C
- A.
?. - B.
?: - C.
let - D.
also - E.
apply
- A.
-
在Kotlin中,以下哪些是函数的特性?答案:A, B, C
- A. 可以省略返回值类型
- B. 可以使用单行函数语法糖
- C. 可以作为参数传递
- D. 必须显式声明返回值类型
- E. 不能作为参数传递
简答题
-
简述Kotlin的单行函数语法糖及其作用。
- 答案:Kotlin的单行函数语法糖允许将函数体直接写在
=符号后面,省略return关键字。这种语法糖使代码更加简洁,适用于函数体只有一行代码的情况。
- 答案:Kotlin的单行函数语法糖允许将函数体直接写在
-
请写出Kotlin中定义一个类的语法,并说明类中可以包含哪些成员。
- 答案:
- 定义类的语法:
class MyClass { var property: String = "Hello" fun myFunction() { println(property) } } - 类中可以包含的成员:
- 属性(Properties):用于存储数据。
- 方法(Methods):用于定义行为。
- 构造函数(Constructors):用于初始化对象。
- 内部类(Inner Classes):定义在类内部的类。
- 伴生对象(Companion Objects):用于定义静态成员。
- 定义类的语法:
- 答案:
-
请解释Kotlin中
val和var的区别。- 答案:
val用于声明不可变变量,一旦赋值后不能更改;var用于声明可变变量,可以多次赋值。
- 答案:
综合题
- 创建一个Kotlin类
Student,包含以下属性和方法:- 属性:
name:学生姓名(不可变变量)age:学生年龄(可变变量)
- 方法:
study():打印“nameis studying. He/She isageyears old.”takeExam():打印“nameis taking an exam.”
- 请写出完整的类定义代码,并创建一个
Student对象,调用其方法。 - 答案:
class Student(val name: String, var age: Int) { fun study() { println("$name is studying. He/She is $age years old.") } fun takeExam() { println("$name is taking an exam.") } } fun main() { val student = Student("Alice", 20) student.study() student.age = 21 student.takeExam() }
- 属性:
好的,以下是第3章的内容,按照调整后的格式进行整理:
第3章 先从看得到的入手,探究Activity
重点知识
- Activity:包含用户界面的组件,用于与用户交互。
- Activity基本用法:
- 手动创建Activity:通过Android Studio创建Empty Views Activity。
- 配置
AndroidManifest.xml:注册Activity。 - 加载布局:使用
setContentView()方法。
- Toast:用于显示短消息。
- 示例:
Toast.makeText(this, "Hello, World!", Toast.LENGTH_SHORT).show()
- 示例:
- Menu:用于创建菜单。
- 示例:
override fun onCreateOptionsMenu(menu: Menu?): Boolean { menuInflater.inflate(R.menu.main, menu) return true }
- 示例:
- Intent:用于组件间通信。
- 显式Intent:指定目标组件。
val intent = Intent(this, SecondActivity::class.java) startActivity(intent) - 隐式Intent:通过action和category指定目标组件。
val intent = Intent(Intent.ACTION_VIEW) intent.data = Uri.parse("https://www.example.com") startActivity(intent)
- 显式Intent:指定目标组件。
- Activity的生命周期:
onCreate():创建时调用。onStart():从不可见到可见时调用。onResume():准备与用户交互时调用。onPause():准备启动或恢复其他Activity时调用。onStop():完全不可见时调用。onDestroy():销毁前调用。onRestart():从停止状态重新启动时调用。
- Activity的启动模式:
standard:每次启动都创建新实例。singleTop:栈顶已存在实例则复用。singleTask:检查栈中实例,存在则复用并清空其上所有Activity。singleInstance:独立栈,全局唯一实例。
- ViewBinding:
- 替代
findViewById,更安全、更方便。 - 示例:
private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) }
- 替代
课后习题
单选题
-
Activity是Android中的一个重要组件,主要用于:答案:B
- A. 后台服务
- B. 用户界面交互
- C. 数据存储
- D. 网络通信
-
在Android中,
Toast的作用是:答案:B- A. 显示长时间的提示信息
- B. 显示短时间的提示信息
- C. 弹出一个对话框
- D. 显示一个菜单
-
Intent在Android中主要用于:答案:B- A. 数据存储
- B. 组件间通信
- C. 网络请求
- D. 用户界面绘制
-
在Android中,
Activity的生命周期方法onCreate()的作用是:答案:A- A. 创建时调用
- B. 从不可见到可见时调用
- C. 准备与用户交互时调用
- D. 准备启动或恢复其他Activity时调用
-
在Android中,
Activity的生命周期方法onResume()的作用是:答案:C- A. 创建时调用
- B. 从不可见到可见时调用
- C. 准备与用户交互时调用
- D. 准备启动或恢复其他Activity时调用
-
在Android中,
Activity的生命周期方法onPause()的作用是:答案:D- A. 创建时调用
- B. 从不可见到可见时调用
- C. 准备与用户交互时调用
- D. 准备启动或恢复其他Activity时调用
-
在Android中,
Activity的生命周期方法onStop()的作用是:答案:B- A. 创建时调用
- B. 完全不可见时调用
- C. 准备与用户交互时调用
- D. 准备启动或恢复其他Activity时调用
-
在Android中,
Activity的生命周期方法onDestroy()的作用是:答案:B- A. 创建时调用
- B. 销毁前调用
- C. 准备与用户交互时调用
- D. 准备启动或恢复其他Activity时调用
-
在Android中,
Activity的生命周期方法onRestart()的作用是:答案:A- A. 从停止状态重新启动时调用
- B. 从不可见到可见时调用
- C. 准备与用户交互时调用
- D. 准备启动或恢复其他Activity时调用
-
在Android中,
Activity的启动模式standard的特点是:答案:A- A. 每次启动都创建新实例
- B. 栈顶已存在实例则复用
- C. 检查栈中实例,存在则复用并清空其上所有Activity
- D. 独立栈,全局唯一实例
-
在Android中,
Activity的启动模式singleTop的特点是:答案:B- A. 每次启动都创建新实例
- B. 栈顶已存在实例则复用
- C. 检查栈中实例,存在则复用并清空其上所有Activity
- D. 独立栈,全局唯一实例
-
在Android中,
Activity的启动模式singleTask的特点是:答案:C- A. 每次启动都创建新实例
- B. 栈顶已存在实例则复用
- C. 检查栈中实例,存在则复用并清空其上所有Activity
- D. 独立栈,全局唯一实例
-
在Android中,
Activity的启动模式singleInstance的特点是:答案:D- A. 每次启动都创建新实例
- B. 栈顶已存在实例则复用
- C. 检查栈中实例,存在则复用并清空其上所有Activity
- D. 独立栈,全局唯一实例
-
在Android中,
ViewBinding的作用是:答案:A- A. 替代
findViewById,更安全、更方便 - B. 用于创建后台服务
- C. 用于网络请求
- D. 用于数据存储
- A. 替代
-
在Android中,
Toast的显示时间Toast.LENGTH_SHORT表示:答案:B- A. 长时间显示
- B. 短时间显示
- C. 永久显示
- D. 不显示
多选题
-
Activity的生命周期中,以下哪些方法是在Activity可见时调用的?答案:B, C
- A.
onCreate() - B.
onStart() - C.
onResume() - D.
onPause()
- A.
-
Activity的启动模式包括以下哪些?答案:A, B, C, D
- A.
standard - B.
singleTop - C.
singleTask - D.
singleInstance
- A.
-
在Android中,以下哪些是
Intent的用途?答案:A, B, C- A. 启动Activity
- B. 启动Service
- C. 发送广播
- D. 创建线程
-
在Android中,以下哪些是
Activity的生命周期方法?答案:A, B, C, D, E, F- A.
onCreate() - B.
onStart() - C.
onResume() - D.
onPause() - E.
onStop() - F.
onDestroy()
- A.
-
在Android中,以下哪些是
Toast的特点?答案:A, B- A. 显示短时间的提示信息
- B. 不需要用户交互
- C. 可以显示长时间的提示信息
- D. 需要用户交互
简答题
-
简述
Activity的生命周期,并说明每个生命周期方法的作用。- 答案:
onCreate():Activity创建时调用,用于初始化资源。onStart():Activity从不可见到可见时调用。onResume():Activity准备与用户交互时调用。onPause():系统准备启动或恢复另一个Activity时调用。onStop():Activity完全不可见时调用。onDestroy():Activity销毁前调用。onRestart():Activity从停止状态重新启动时调用。
- 答案:
-
请解释
Intent的作用,并给出显式Intent和隐式Intent的区别。- 答案:
Intent用于组件间通信,包括启动Activity、Service和发送Broadcast。- 显式Intent:明确指定目标组件的名称,通常用于内部组件间的通信。
- 隐式Intent:通过action和category等信息指定目标组件,通常用于跨应用通信。
- 答案:
-
简述
Activity的启动模式及其特点。- 答案:
standard:每次启动都创建新实例。singleTop:栈顶已存在实例则复用。singleTask:检查栈中实例,存在则复用并清空其上所有Activity。singleInstance:独立栈,全局唯一实例。
- 答案:
综合题
- 创建一个名为
FirstActivity的Activity,并在其中添加一个按钮。当点击按钮时,使用显式Intent跳转到SecondActivity。请写出FirstActivity和SecondActivity的代码,以及AndroidManifest.xml中的注册代码。- 答案:
- FirstActivity代码:
class FirstActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_first) val button: Button = findViewById(R.id.button) button.setOnClickListener { val intent = Intent(this, SecondActivity::class.java) startActivity(intent) } } } - SecondActivity代码:
class SecondActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_second) } } - AndroidManifest.xml注册代码:
<application ...> <activity android:name=".FirstActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".SecondActivity" /> </application>
- FirstActivity代码:
- 答案:
以上是第3章的内容,后续章节将按照同样的格式进行整理。
好的,以下是第4章的内容,按照调整后的格式进行整理:
第4章 软件也要拼脸蛋,UI开发的点点滴滴
重点知识
-
常用控件:
- TextView:用于显示文本信息。
<TextView android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Hello, World!" /> - Button:用于用户交互。
<Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Click Me" /> - EditText:用于输入文本。
<EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Enter text here" /> - ImageView:用于显示图片。
<ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/image" /> - ProgressBar:用于显示进度。
<ProgressBar android:id="@+id/progressBar" android:layout_width="match_parent" android:layout_height="wrap_content" /> - AlertDialog:用于显示对话框。
AlertDialog.Builder(this).apply { setTitle("Title") setMessage("Message") setPositiveButton("OK") { dialog, which -> } setNegativeButton("Cancel") { dialog, which -> } show() }
- TextView:用于显示文本信息。
-
布局:
- LinearLayout:线性布局,控件按顺序排列。
<LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:text="Button 1" ... /> <Button android:text="Button 2" ... /> </LinearLayout> - RelativeLayout:相对布局,控件相对位置。
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button1" android:layout_alignParentTop="true" android:text="Button 1" ... /> <Button android:layout_below="@id/button1" android:text="Button 2" ... /> </RelativeLayout> - FrameLayout:帧布局,控件堆叠。
<FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:text="Text" ... /> <Button android:text="Button" ... /> </FrameLayout>
- LinearLayout:线性布局,控件按顺序排列。
-
RecyclerView:
- 基本步骤:
- 添加依赖库。
- 在布局文件中添加
RecyclerView。 - 定义实体类和子项布局。
- 创建
Adapter和ViewHolder。 - 设置
LayoutManager和Adapter。
- 示例代码:
class FruitAdapter(val fruitList: List<Fruit>) : RecyclerView.Adapter<FruitAdapter.ViewHolder>() { inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { val fruitImage: ImageView = view.findViewById(R.id.fruitImage) val fruitName: TextView = view.findViewById(R.id.fruitName) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.fruit_item, parent, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val fruit = fruitList[position] holder.fruitImage.setImageResource(fruit.imageId) holder.fruitName.text = fruit.name } override fun getItemCount() = fruitList.size }
- 基本步骤:
课后习题
单选题
-
在Android中,
TextView用于:答案:B- A. 显示图片
- B. 显示文本
- C. 按钮点击
- D. 输入文本
-
RecyclerView的主要优点是:答案:C- A. 支持多种布局
- B. 数据自动刷新
- C. 高效的视图复用
- D. 简单的布局管理
-
LinearLayout的orientation属性可以设置为:答案:A, B- A. horizontal
- B. vertical
- C. both
- D. none
-
在Android中,
Button的作用是:答案:B- A. 显示文本
- B. 用户交互
- C. 输入文本
- D. 显示图片
-
在Android中,
EditText的作用是:答案:D- A. 显示文本
- B. 用户交互
- C. 显示图片
- D. 输入文本
-
在Android中,
ImageView的作用是:答案:D- A. 显示文本
- B. 用户交互
- C. 输入文本
- D. 显示图片
-
在Android中,
ProgressBar的作用是:答案:B- A. 显示文本
- B. 显示进度
- C. 输入文本
- D. 显示图片
-
在Android中,
AlertDialog的作用是:答案:B- A. 显示文本
- B. 显示对话框
- C. 输入文本
- D. 显示图片
-
在Android中,
LinearLayout的orientation属性默认值是:答案:B- A. horizontal
- B. vertical
- C. both
- D. none
-
在Android中,
RelativeLayout的特点是:答案:C- A. 控件按顺序排列
- B. 控件堆叠
- C. 控件相对位置
- D. 控件网格排列
-
在Android中,
FrameLayout的特点是:答案:B- A. 控件按顺序排列
- B. 控件堆叠
- C. 控件相对位置
- D. 控件网格排列
-
在Android中,
RecyclerView的Adapter的作用是:答案:C- A. 管理布局
- B. 提供数据
- C. 绑定数据到视图
- D. 管理线程
-
在Android中,
RecyclerView的ViewHolder的作用是:答案:B- A. 管理布局
- B. 缓存视图
- C. 绑定数据到视图
- D. 管理线程
-
在Android中,
RecyclerView的LayoutManager的作用是:答案:A- A. 管理布局
- B. 提供数据
- C. 绑定数据到视图
- D. 管理线程
-
在Android中,
RecyclerView的Adapter必须实现的方法是:答案:D- A.
onCreateViewHolder() - B.
onBindViewHolder() - C.
getItemCount() - D. 所有以上选项
- A.
多选题
-
以下哪些是Android中的常用控件?答案:A, B, C, D
- A. TextView
- B. Button
- C. EditText
- D. ImageView
-
RecyclerView的使用步骤包括以下哪些?答案:A, B, C, D- A. 添加依赖库
- B. 定义实体类和子项布局
- C. 创建
Adapter和ViewHolder - D. 设置
LayoutManager和Adapter
-
在Android中,以下哪些是布局类型?答案:A, B, C
- A. LinearLayout
- B. RelativeLayout
- C. FrameLayout
- D. RecyclerView
-
在Android中,以下哪些是
RecyclerView的特性?答案:A, B, C- A. 高效的视图复用
- B. 支持多种布局
- C. 数据绑定
- D. 自动刷新
-
在Android中,以下哪些是
AlertDialog的常用方法?答案:A, B, C- A.
setTitle() - B.
setMessage() - C.
setPositiveButton() - D.
setNegativeButton()
- A.
简答题
-
简述
LinearLayout和RelativeLayout的区别。- 答案:
LinearLayout:线性布局,控件按顺序排列,支持水平或垂直方向。RelativeLayout:相对布局,控件相对位置,可以指定控件相对于父布局或其他控件的位置。
- 答案:
-
请解释
RecyclerView的工作原理。- 答案:
RecyclerView通过Adapter和ViewHolder模式高效地复用视图。Adapter负责提供数据和视图绑定逻辑。ViewHolder用于缓存视图,减少findViewById的调用,提高性能。LayoutManager负责管理布局,支持多种布局方式(如线性、网格等)。
- 答案:
-
简述
RecyclerView的Adapter、ViewHolder和LayoutManager的作用。- 答案:
Adapter:负责提供数据和视图绑定逻辑。ViewHolder:用于缓存视图,减少findViewById的调用,提高性能。LayoutManager:负责管理布局,支持多种布局方式(如线性、网格等)。
- 答案:
综合题
- 创建一个名为
MainActivity的Activity,并在其中使用RecyclerView显示一个水果列表。水果列表包含水果名称和图片。请写出MainActivity的代码,以及RecyclerView的适配器代码和布局文件。- 答案:
- MainActivity代码:
class MainActivity : AppCompatActivity() { private val fruitList = listOf( Fruit("Apple", R.drawable.apple_pic), Fruit("Banana", R.drawable.banana_pic), Fruit("Orange", R.drawable.orange_pic) ) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val recyclerView: RecyclerView = findViewById(R.id.recyclerView) val layoutManager = LinearLayoutManager(this) recyclerView.layoutManager = layoutManager val adapter = FruitAdapter(fruitList) recyclerView.adapter = adapter } } - FruitAdapter代码:
class FruitAdapter(val fruitList: List<Fruit>) : RecyclerView.Adapter<FruitAdapter.ViewHolder>() { inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { val fruitImage: ImageView = view.findViewById(R.id.fruitImage) val fruitName: TextView = view.findViewById(R.id.fruitName) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.fruit_item, parent, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val fruit = fruitList[position] holder.fruitImage.setImageResource(fruit.imageId) holder.fruitName.text = fruit.name } override fun getItemCount() = fruitList.size } - fruit_item布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="8dp"> <ImageView android:id="@+id/fruitImage" android:layout_width="40dp" android:layout_height="40dp" android:src="@drawable/ic_launcher_background" /> <TextView android:id="@+id/fruitName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginStart="16dp" android:text="Fruit Name" android:textSize="16sp" /> </LinearLayout> - activity_main布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
- MainActivity代码:
- 答案:
第5章 手机平板要兼顾,探究Fragment
重点知识
- Fragment:嵌入在Activity中的UI片段,用于合理利用大屏幕空间。
- Fragment基本用法:
- 定义Fragment的布局文件。
- 创建Fragment类,重写
onCreateView()方法。 - 在Activity布局中使用
<fragment>标签引入Fragment。
- 动态添加Fragment:
- 使用
FragmentManager和FragmentTransaction动态添加或替换Fragment。 - 示例:
val fragmentManager = supportFragmentManager val transaction = fragmentManager.beginTransaction() transaction.replace(R.id.fragment_container, MyFragment()) transaction.commit()
- 使用
- Fragment生命周期:
onAttach():Fragment与Activity关联时调用。onCreateView():创建视图时调用。onActivityCreated():Activity创建完成后调用。onDestroyView():视图销毁时调用。onDetach():Fragment与Activity解除关联时调用。
- 限定符:
large:用于大屏幕设备。smallest-width:根据最小宽度加载布局。- 示例:
res/layout-large/activity_main.xml res/layout-sw600dp/activity_main.xml
课后习题
单选题
-
Fragment主要用于:答案:B
- A. 后台服务
- B. 用户界面片段
- C. 数据存储
- D. 网络通信
-
在Android中,动态添加Fragment时,使用以下哪个类进行管理?答案:A
- A.
FragmentManager - B.
FragmentTransaction - C.
FragmentActivity - D.
Fragment
- A.
-
Fragment的生命周期中,
onAttach()方法的作用是:答案:B- A. 创建视图
- B. Fragment与Activity关联时调用
- C. 销毁视图
- D. 解除与Activity的关联
-
在Android中,
Fragment的onCreateView()方法返回的是:答案:B- A.
Fragment - B.
View - C.
Activity - D.
Context
- A.
-
在Android中,
Fragment的onActivityCreated()方法的作用是:答案:C- A. 创建视图
- B. Fragment与Activity关联时调用
- C. Activity创建完成后调用
- D. 销毁视图
-
在Android中,
Fragment的onDestroyView()方法的作用是:答案:C- A. 创建视图
- B. Fragment与Activity关联时调用
- C. 视图销毁时调用
- D. 解除与Activity的关联
-
在Android中,
Fragment的onDetach()方法的作用是:答案:D- A. 创建视图
- B. Fragment与Activity关联时调用
- C. 销毁视图
- D. 解除与Activity的关联
-
在Android中,
Fragment的onAttach()方法的参数是:答案:C- A.
Fragment - B.
View - C.
Context - D.
Activity
- A.
-
在Android中,
Fragment的onCreateView()方法的参数不包括:答案:D- A.
inflater: LayoutInflater - B.
container: ViewGroup? - C.
savedInstanceState: Bundle? - D.
context: Context
- A.
-
在Android中,
Fragment的onActivityCreated()方法的参数是:答案:C- A.
Fragment - B.
View - C.
Bundle? - D.
Context
- A.
-
在Android中,
Fragment的onDestroyView()方法的参数是:答案:None- A.
Fragment - B.
View - C.
Bundle? - D.
Context
- A.
-
在Android中,
Fragment的onDetach()方法的参数是:答案:None- A.
Fragment - B.
View - C.
Bundle? - D.
Context
- A.
-
在Android中,
Fragment的onCreateView()方法中,inflater的作用是:答案:A- A. 用于布局文件的解析
- B. 用于创建视图
- C. 用于保存实例状态
- D. 用于销毁视图
-
在Android中,
Fragment的onActivityCreated()方法中,savedInstanceState的作用是:答案:C- A. 用于创建视图
- B. 用于销毁视图
- C. 用于保存实例状态
- D. 用于关联Activity
-
在Android中,
Fragment的onDestroyView()方法中,view的作用是:答案:None- A. 用于创建视图
- B. 用于销毁视图
- C. 用于保存实例状态
- D. 用于关联Activity
多选题
-
Fragment的生命周期方法包括以下哪些?答案:A, B, C, D, E
- A.
onAttach() - B.
onCreateView() - C.
onActivityCreated() - D.
onDestroyView() - E.
onDetach()
- A.
-
Fragment的使用场景包括以下哪些?答案:A, B, C
- A. 在平板上合理利用大屏幕空间
- B. 动态添加或替换UI片段
- C. 实现复杂的布局结构
- D. 替代Activity
-
在Android中,以下哪些是Fragment的生命周期方法?答案:A, B, C, D, E
- A.
onAttach() - B.
onCreateView() - C.
onActivityCreated() - D.
onDestroyView() - E.
onDetach()
- A.
-
在Android中,以下哪些是Fragment的特性?答案:A, B, C
- A. 可以嵌入在Activity中
- B. 可以动态添加或替换
- C. 可以保存实例状态
- D. 可以替代Activity
-
在Android中,以下哪些是Fragment的生命周期回调方法?答案:A, B, C, D, E
- A.
onAttach() - B.
onCreateView() - C.
onActivityCreated() - D.
onDestroyView() - E.
onDetach()
- A.
简答题
-
简述Fragment与Activity的关系。
- 答案:
- Fragment嵌入在Activity中,依赖于Activity的生命周期。
- Activity可以包含多个Fragment,Fragment可以动态添加、替换或移除。
- 答案:
-
请解释Fragment的生命周期方法
onCreateView()和onActivityCreated()的区别。- 答案:
onCreateView():创建Fragment的视图时调用,返回Fragment的根视图。onActivityCreated():Activity创建完成后调用,用于初始化Fragment的其他组件。
- 答案:
-
简述Fragment的生命周期。
- 答案:
onAttach():Fragment与Activity关联时调用。onCreateView():创建视图时调用。onActivityCreated():Activity创建完成后调用。onDestroyView():视图销毁时调用。onDetach():Fragment与Activity解除关联时调用。
- 答案:
综合题
- 创建一个名为
MainActivity的Activity,并在其中动态添加两个Fragment:LeftFragment和RightFragment。LeftFragment包含一个按钮,点击按钮时动态替换RightFragment为AnotherRightFragment。请写出MainActivity、LeftFragment、RightFragment和AnotherRightFragment的代码,以及AndroidManifest.xml中的注册代码。- 答案:
- MainActivity代码:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) if (savedInstanceState == null) { supportFragmentManager.beginTransaction() .add(R.id.left_fragment_container, LeftFragment()) .add(R.id.right_fragment_container, RightFragment()) .commit() } } } - LeftFragment代码:
class LeftFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val view = inflater.inflate(R.layout.fragment_left, container, false) val button: Button = view.findViewById(R.id.button) button.setOnClickListener { val fragmentManager = parentFragmentManager val transaction = fragmentManager.beginTransaction() transaction.replace(R.id.right_fragment_container, AnotherRightFragment()) transaction.commit() } return view } } - RightFragment代码:
class RightFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_right, container, false) } } - AnotherRightFragment代码:
class AnotherRightFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_another_right, container, false) } } - activity_main布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <FrameLayout android:id="@+id/left_fragment_container" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" /> <FrameLayout android:id="@+id/right_fragment_container" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" /> </LinearLayout> - fragment_left布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Replace Fragment" /> </LinearLayout> - fragment_right布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Right Fragment" /> </LinearLayout> - fragment_another_right布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Another Right Fragment" /> </LinearLayout> - AndroidManifest.xml注册代码:
<application ...> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
- MainActivity代码:
- 答案:
第6章 全局大喇叭,详解广播机制
重点知识
- 广播机制:Android提供的一种组件间通信机制。
- 广播分类:
- 标准广播:异步执行,无先后顺序。
- 有序广播:同步执行,有先后顺序,可被截断。
- 注册广播接收器:
- 动态注册:在代码中注册,需在
onDestroy()中注销。val intentFilter = IntentFilter("android.intent.action.TIME_TICK") val receiver = TimeChangeReceiver() registerReceiver(receiver, intentFilter) - 静态注册:在
AndroidManifest.xml中注册。<receiver android:name=".BootCompleteReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
- 动态注册:在代码中注册,需在
- 发送广播:
- 标准广播:
val intent = Intent("com.example.MY_BROADCAST") sendBroadcast(intent) - 有序广播:
val intent = Intent("com.example.MY_BROADCAST") sendOrderedBroadcast(intent, null)
- 标准广播:
- 广播优先级:
- 在
AndroidManifest.xml中通过android:priority设置。 - 动态注册通过
IntentFilter设置。
- 在
- 广播截断:
- 在
onReceive()中调用abortBroadcast()。
- 在
- 运行时权限:
- 需在
AndroidManifest.xml中声明权限。 - 示例:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
- 需在
课后习题
单选题
-
在Android中,标准广播的特点是:答案:D
- A. 同步执行
- B. 有先后顺序
- C. 可被截断
- D. 异步执行
-
动态注册的广播接收器需要在何时注销?答案:C
- A.
onCreate() - B.
onStart() - C.
onDestroy() - D.
onPause()
- A.
-
在Android中,发送有序广播的方法是:答案:B
- A.
sendBroadcast() - B.
sendOrderedBroadcast() - C.
sendStickyBroadcast() - D.
sendBroadcastAsUser()
- A.
-
在Android中,广播接收器的
onReceive()方法中,调用哪个方法可以截断广播?答案:A- A.
abortBroadcast() - B.
stopBroadcast() - C.
cancelBroadcast() - D.
endBroadcast()
- A.
-
在Android中,
IntentFilter的作用是:答案:B- A. 发送广播
- B. 过滤广播
- C. 注册广播
- D. 接收广播
-
在Android中,
BroadcastReceiver的onReceive()方法的参数是:答案:B- A.
Context和Intent - B.
Context和Intent - C.
Intent和Bundle - D.
Context和Bundle
- A.
-
在Android中,
BroadcastReceiver的onReceive()方法中,Intent的作用是:答案:A- A. 携带广播数据
- B. 注册广播
- C. 发送广播
- D. 接收广播
-
在Android中,
BroadcastReceiver的onReceive()方法中,Context的作用是:答案:C- A. 发送广播
- B. 注册广播
- C. 提供上下文环境
- D. 接收广播
-
在Android中,
BroadcastReceiver的onReceive()方法中,abortBroadcast()的作用是:答案:A- A. 截断广播
- B. 停止广播
- C. 取消广播
- D. 结束广播
-
在Android中,
BroadcastReceiver的onReceive()方法中,IntentFilter的作用是:答案:B- A. 发送广播
- B. 过滤广播
- C. 注册广播
- D. 接收广播
-
在Android中,
BroadcastReceiver的onReceive()方法中,Context的作用是:答案:C- A. 发送广播
- B. 注册广播
- C. 提供上下文环境
- D. 接收广播
-
在Android中,
BroadcastReceiver的onReceive()方法中,Intent的作用是:答案:A- A. 携带广播数据
- B. 注册广播
- C. 发送广播
- D. 接收广播
-
在Android中,
BroadcastReceiver的onReceive()方法中,abortBroadcast()的作用是:答案:A- A. 截断广播
- B. 停止广播
- C. 取消广播
- D. 结束广播
-
在Android中,
BroadcastReceiver的onReceive()方法中,IntentFilter的作用是:答案:B- A. 发送广播
- B. 过滤广播
- C. 注册广播
- D. 接收广播
-
在Android中,
BroadcastReceiver的onReceive()方法中,Context的作用是:答案:C- A. 发送广播
- B. 注册广播
- C. 提供上下文环境
- D. 接收广播
多选题
-
广播的分类包括以下哪些?答案:A, B
- A. 标准广播
- B. 有序广播
- C. 系统广播
- D. 自定义广播
-
广播接收器的注册方式包括以下哪些?答案:A, B
- A. 动态注册
- B. 静态注册
- C. 临时注册
- D. 永久注册
-
在Android中,以下哪些是广播接收器的生命周期方法?答案:A
- A.
onReceive() - B.
onCreate() - C.
onStart() - D.
onDestroy()
- A.
-
在Android中,以下哪些是广播的特性?答案:A, B, C
- A. 可以异步执行
- B. 可以同步执行
- C. 可以被截断
- D. 可以替代Activity
-
在Android中,以下哪些是广播的用途?答案:A, B, C
- A. 组件间通信
- B. 监听系统事件
- C. 应用间通信
- D. 替代Service
简答题
-
简述广播接收器的生命周期。
- 答案:
- 广播接收器的生命周期较短,主要方法是
onReceive()。 onReceive():接收广播时调用,用于处理广播事件。
- 广播接收器的生命周期较短,主要方法是
- 答案:
-
请解释有序广播的特点。
- 答案:
- 有序广播是同步执行的。
- 广播接收器有先后顺序,优先级高的先接收。
- 前一个接收器可以截断广播,阻止后续接收器接收。
- 答案:
-
简述广播的分类及其特点。
- 答案:
- 标准广播:异步执行,无先后顺序。
- 有序广播:同步执行,有先后顺序,可被截断。
- 答案:
综合题
- 创建一个名为
MainActivity的Activity,并在其中动态注册一个广播接收器TimeChangeReceiver,用于接收系统时间变化的广播。当接收到广播时,弹出一个Toast提示用户。请写出MainActivity和TimeChangeReceiver的代码。- 答案:
- MainActivity代码:
class MainActivity : AppCompatActivity() { private lateinit var timeChangeReceiver: TimeChangeReceiver override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val intentFilter = IntentFilter("android.intent.action.TIME_TICK") timeChangeReceiver = TimeChangeReceiver() registerReceiver(timeChangeReceiver, intentFilter) } override fun onDestroy() { super.onDestroy() unregisterReceiver(timeChangeReceiver) } } - TimeChangeReceiver代码:
class TimeChangeReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { Toast.makeText(context, "Time has changed", Toast.LENGTH_SHORT).show() } }
- MainActivity代码:
- 答案:
第7章 数据存储全方案,详解持久化技术
重点知识
- 数据持久化:将内存中的数据保存到存储设备中,确保数据在设备关机后仍然存在。
- 文件存储:
- 数据保存到文件中,适合存储简单文本或二进制数据。
- 示例:
val output = openFileOutput("data", Context.MODE_PRIVATE) val writer = BufferedWriter(OutputStreamWriter(output)) writer.use { it.write("Hello, World!") }
- SharedPreferences存储:
- 使用键值对存储数据,适合存储简单的配置信息。
- 示例:
val editor = getSharedPreferences("data", Context.MODE_PRIVATE).edit() editor.putString("name", "Tom") editor.apply()
- SQLite数据库存储:
- 轻量级关系型数据库,适合存储结构化数据。
- 示例:
class MyDatabaseHelper(context: Context, name: String, version: Int) : SQLiteOpenHelper(context, name, null, version) { private val createBook = "create table Book (" + "id integer primary key autoincrement," + "author text," + "price real," + "pages integer," + "name text)" override fun onCreate(db: SQLiteDatabase) { db.execSQL(createBook) } override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { db.execSQL("drop table if exists Book") onCreate(db) } }
- 数据库操作:
- 插入数据:
val values = ContentValues().apply { put("name", "The Da Vinci Code") put("author", "Dan Brown") put("pages", 454) put("price", 16.96) } val db = MyDatabaseHelper(this, "BookStore.db", 1).writableDatabase db.insert("Book", null, values) - 更新数据:
val values = ContentValues().apply { put("price", 10.99) } db.update("Book", values, "name = ?", arrayOf("The Da Vinci Code")) - 删除数据:
db.delete("Book", "pages > ?", arrayOf("500")) - 查询数据:
val cursor = db.query("Book", null, null, null, null, null, null) if (cursor.moveToFirst()) { do { val name = cursor.getString(cursor.getColumnIndex("name")) val author = cursor.getString(cursor.getColumnIndex("author")) val pages = cursor.getInt(cursor.getColumnIndex("pages")) val price = cursor.getDouble(cursor.getColumnIndex("price")) Log.d("MainActivity", "book name is $name") } while (cursor.moveToNext()) } cursor.close()
- 插入数据:
课后习题
单选题
-
在Android中,文件存储的数据默认保存在哪个目录下?答案:A
- A.
/data/data/<package name>/files/ - B.
/sdcard/ - C.
/data/data/<package name>/shared_prefs/ - D.
/data/data/<package name>/databases/
- A.
-
SharedPreferences存储的数据以什么形式保存?答案:A- A. XML文件
- B. 数据库
- C. 二进制文件
- D. 文本文件
-
在Android中,
SQLiteOpenHelper的onCreate()方法的作用是:答案:A- A. 创建数据库
- B. 更新数据库
- C. 删除数据库
- D. 查询数据库
-
在Android中,
SharedPreferences的edit()方法返回的是:答案:B- A.
SharedPreferences - B.
SharedPreferences.Editor - C.
Context - D.
Editor
- A.
-
在Android中,
SQLiteOpenHelper的onUpgrade()方法的作用是:答案:B- A. 创建数据库
- B. 更新数据库
- C. 删除数据库
- D. 查询数据库
-
在Android中,
SharedPreferences的apply()方法的作用是:答案:B- A. 保存数据
- B. 提交数据
- C. 清除数据
- D. 查询数据
-
在Android中,
SQLiteOpenHelper的onCreate()方法中,db.execSQL()的作用是:答案:A- A. 执行SQL语句
- B. 查询数据
- C. 更新数据
- D. 删除数据
-
在Android中,
SharedPreferences的putString()方法的作用是:答案:B- A. 保存整型数据
- B. 保存字符串数据
- C. 保存布尔型数据
- D. 保存浮点型数据
-
在Android中,
SQLiteOpenHelper的onUpgrade()方法中,db.execSQL("drop table if exists Book")的作用是:答案:C- A. 创建表
- B. 更新表
- C. 删除表
- D. 查询表
-
在Android中,
SharedPreferences的getString()方法的作用是:答案:B- A. 保存字符串数据
- B. 查询字符串数据
- C. 更新字符串数据
- D. 删除字符串数据
-
在Android中,
SQLiteOpenHelper的onCreate()方法中,db.execSQL(createBook)的作用是:答案:A- A. 创建表
- B. 更新表
- C. 删除表
- D. 查询表
-
在Android中,
SharedPreferences的putInt()方法的作用是:答案:A- A. 保存整型数据
- B. 查询整型数据
- C. 更新整型数据
- D. 删除整型数据
-
在Android中,
SQLiteOpenHelper的onUpgrade()方法中,db.execSQL("drop table if exists Book")的作用是:答案:C- A. 创建表
- B. 更新表
- C. 删除表
- D. 查询表
-
在Android中,
SharedPreferences的getString()方法的参数是:答案:B- A. 键值对
- B. 键和默认值
- C. 键和值
- D. 键和类型
-
在Android中,
SQLiteOpenHelper的onCreate()方法中,db.execSQL(createBook)的作用是:答案:A- A. 创建表
- B. 更新表
- C. 删除表
- D. 查询表
多选题
-
Android中支持的数据存储方式包括以下哪些?答案:A, B, C
- A. 文件存储
- B. SharedPreferences存储
- C. SQLite数据库存储
- D. 网络存储
-
数据库操作中,以下哪些是
SQLiteDatabase类提供的方法?答案:A, B, C, D- A.
insert() - B.
update() - C.
delete() - D.
query()
- A.
-
在Android中,以下哪些是
SharedPreferences的常用方法?答案:A, B, C, D- A.
putString() - B.
putInt() - C.
getString() - D.
getInt()
- A.
-
在Android中,以下哪些是
SQLiteOpenHelper的常用方法?答案:A, B, C- A.
onCreate() - B.
onUpgrade() - C.
getWritableDatabase() - D.
getReadableDatabase()
- A.
-
在Android中,以下哪些是
SharedPreferences.Editor的常用方法?答案:A, B, C- A.
putString() - B.
putInt() - C.
apply() - D.
commit()
- A.
简答题
-
简述文件存储和SharedPreferences存储的区别。
- 答案:
- 文件存储:用于存储复杂的数据或大型文件,如图片、视频等。
- SharedPreferences存储:用于存储简单的键值对数据,适合存储配置信息。
- 答案:
-
请解释
SQLiteOpenHelper的onUpgrade()方法的作用。- 答案:
- 当数据库版本升级时,
onUpgrade()方法被调用,用于更新数据库结构。
- 当数据库版本升级时,
- 答案:
-
简述
SharedPreferences的存储和读取逻辑。- 答案:
- 存储:
val editor = getSharedPreferences("data", Context.MODE_PRIVATE).edit() editor.putString("name", "Tom") editor.apply() - 读取:
val sharedPreferences = getSharedPreferences("data", Context.MODE_PRIVATE) val name = sharedPreferences.getString("name", "")
- 存储:
- 答案:
综合题
- 创建一个名为
MainActivity的Activity,并在其中使用SharedPreferences存储用户输入的姓名和年龄。请写出MainActivity的代码,以及SharedPreferences的存储和读取逻辑。- 答案:
- MainActivity代码:
class MainActivity : AppCompatActivity() { private lateinit var sharedPreferences: SharedPreferences private lateinit var editor: SharedPreferences.Editor override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) sharedPreferences = getSharedPreferences("user_data", Context.MODE_PRIVATE) editor = sharedPreferences.edit() val nameEditText: EditText = findViewById(R.id.nameEditText) val ageEditText: EditText = findViewById(R.id.ageEditText) val saveButton: Button = findViewById(R.id.saveButton) saveButton.setOnClickListener { val name = nameEditText.text.toString() val age = ageEditText.text.toString() editor.putString("name", name) editor.putInt("age", age.toInt()) editor.apply() Toast.makeText(this, "Data saved", Toast.LENGTH_SHORT).show() } val loadButton: Button = findViewById(R.id.loadButton) loadButton.setOnClickListener { val name = sharedPreferences.getString("name", "") val age = sharedPreferences.getInt("age", 0) nameEditText.setText(name) ageEditText.setText(age.toString()) Toast.makeText(this, "Data loaded", Toast.LENGTH_SHORT).show() } } } - activity_main布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <EditText android:id="@+id/nameEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Enter name" /> <EditText android:id="@+id/ageEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Enter age" /> <Button android:id="@+id/saveButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Save" /> <Button android:id="@+id/loadButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Load" /> </LinearLayout>
- MainActivity代码:
- 答案:
第8章 跨程序共享数据,探究ContentProvider
重点知识
- ContentProvider:Android四大组件之一,用于跨程序共享数据。
- 权限机制:
- 安装时权限:用户安装应用时自动授予。
- 运行时权限:用户在应用运行时授予。
- 特殊权限:由系统或设备制造商定义。
- 运行时权限请求:
- 在
AndroidManifest.xml中声明权限。 - 使用
ContextCompat.checkSelfPermission()检查权限。 - 使用
ActivityCompat.requestPermissions()请求权限。
- 在
- ContentResolver:用于访问ContentProvider提供的数据。
- ContentProvider的创建:
- 继承
ContentProvider类,重写onCreate()、query()、insert()、update()、delete()和getType()方法。
- 继承
- UriMatcher:用于匹配ContentProvider的URI。
课后习题
单选题
-
在Android中,
ContentProvider主要用于:答案:B- A. 网络通信
- B. 跨程序共享数据
- C. 数据存储
- D. 用户界面
-
在Android中,运行时权限需要在何时请求?答案:B
- A. 应用安装时
- B. 应用运行时
- C. 应用卸载时
- D. 应用更新时
-
在Android中,
ContentResolver的作用是:答案:C- A. 创建数据库
- B. 更新UI
- C. 访问ContentProvider提供的数据
- D. 管理线程
-
在Android中,
UriMatcher的作用是:答案:D- A. 创建数据库
- B. 更新UI
- C. 访问ContentProvider提供的数据
- D. 匹配ContentProvider的URI
-
在Android中,
ContentProvider的onCreate()方法的作用是:答案:A- A. 初始化ContentProvider
- B. 查询数据
- C. 更新数据
- D. 删除数据
-
在Android中,
ContentProvider的query()方法的作用是:答案:B- A. 创建数据库
- B. 查询数据
- C. 更新数据
- D. 删除数据
-
在Android中,
ContentProvider的insert()方法的作用是:答案:C- A. 创建数据库
- B. 查询数据
- C. 插入数据
- D. 删除数据
-
在Android中,
ContentProvider的update()方法的作用是:答案:C- A. 创建数据库
- B. 查询数据
- C. 更新数据
- D. 删除数据
-
在Android中,
ContentProvider的delete()方法的作用是:答案:D- A. 创建数据库
- B. 查询数据
- C. 更新数据
- D. 删除数据
-
在Android中,
ContentProvider的getType()方法的作用是:答案:E- A. 创建数据库
- B. 查询数据
- C. 更新数据
- D. 删除数据
- E. 获取数据的MIME类型
-
在Android中,
ContentProvider的onCreate()方法的作用是:答案:A- A. 初始化ContentProvider
- B. 查询数据
- C. 更新数据
- D. 删除数据
-
在Android中,
ContentProvider的query()方法的作用是:答案:B- A. 创建数据库
- B. 查询数据
- C. 更新数据
- D. 删除数据
-
在Android中,
ContentProvider的insert()方法的作用是:答案:C- A. 创建数据库
- B. 查询数据
- C. 插入数据
- D. 删除数据
-
在Android中,
ContentProvider的update()方法的作用是:答案:C- A. 创建数据库
- B. 查询数据
- C. 更新数据
- D. 删除数据
-
在Android中,
ContentProvider的delete()方法的作用是:答案:D- A. 创建数据库
- B. 查询数据
- C. 更新数据
- D. 删除数据
多选题
-
在Android中,以下哪些是
ContentProvider的生命周期方法?答案:A, B, C, D, E- A.
onCreate() - B.
query() - C.
insert() - D.
update() - E.
delete()
- A.
-
在Android中,以下哪些是
ContentProvider的特性?答案:A, B, C- A. 跨程序共享数据
- B. 提供数据访问接口
- C. 支持多种数据类型
- D. 管理线程
-
在Android中,以下哪些是
ContentResolver的特性?答案:A, B, C- A. 查询数据
- B. 插入数据
- C. 更新数据
- D. 删除数据
-
在Android中,以下哪些是
UriMatcher的特性?答案:A, B, C- A. 匹配ContentProvider的URI
- B. 提供数据访问接口
- C. 支持多种数据类型
- D. 管理线程
-
在Android中,以下哪些是
ContentProvider的生命周期方法?答案:A, B, C, D, E- A.
onCreate() - B.
query() - C.
insert() - D.
update() - E.
delete()
- A.
简答题
-
简述
ContentProvider的作用。- 答案:
ContentProvider用于跨程序共享数据,允许一个应用访问另一个应用的数据。
- 答案:
-
简述
ContentResolver的作用。- 答案:
ContentResolver用于访问ContentProvider提供的数据,通过Uri来查询、插入、更新和删除数据。
- 答案:
-
简述
UriMatcher的作用。- 答案:
UriMatcher用于匹配ContentProvider的Uri,通过addURI()方法添加匹配规则,简化Uri的处理逻辑。
- 答案:
综合题
- 创建一个名为
MyProvider的ContentProvider,并定义一个名为table1的表。在table1表中存储用户信息,包括用户ID、用户名和用户年龄。请写出MyProvider的代码,以及在MainActivity中访问table1表的代码。- 答案:
-
MyProvider代码:
class MyProvider : ContentProvider() { private lateinit var dbHelper: MyDatabaseHelper override fun onCreate(): Boolean { dbHelper = MyDatabaseHelper(context!!) return true } override fun query(uri: Uri, projection: Array<String>?, selection: String?, selectionArgs: Array<String>?, sortOrder: String?): Cursor? { return dbHelper.writableDatabase.query("table1", projection, selection, selectionArgs, null, null, sortOrder) } override fun insert(uri: Uri, values: ContentValues?): Uri? { val rowId = dbHelper.writableDatabase.insert("table1", null, values) return Uri.withAppendedPath(uri, rowId.toString()) } override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<String>?): Int { return dbHelper.writableDatabase.update("table1", values, selection, selectionArgs) } override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int { return dbHelper.writableDatabase.delete("table1", selection, selectionArgs) } override fun getType(uri: Uri): String? { return when (uriMatcher.match(uri)) { 1 -> "vnd.android.cursor.dir/vnd.com.example.app.provider.table1" 2 -> "vnd.android.cursor.item/vnd.com.example.app.provider.table1" else -> null } } } -
MainActivity代码:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val user = User("John Doe", 30) val values = ContentValues().apply { put("name", user.name) put("age", user.age) } val uri = Uri.parse("content://com.example.app.provider/table1") contentResolver.insert(uri, values) val cursor = contentResolver.query(uri, null, null, null, null) cursor?.use { if (it.moveToFirst()) { do { val name = it.getString(it.getColumnIndex("name")) val age = it.getInt(it.getColumnIndex("age")) Log.d("MainActivity", "Name: $name, Age: $age") } while (it.moveToNext()) } } } } -
MyDatabaseHelper代码:
class MyDatabaseHelper(context: Context) : SQLiteOpenHelper(context, "MyDatabase.db", null, 1) { private val createTable1 = "CREATE TABLE table1 (" + "id INTEGER PRIMARY KEY AUTOINCREMENT," + "name TEXT," + "age INTEGER)" override fun onCreate(db: SQLiteDatabase) { db.execSQL(createTable1) } override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { db.execSQL("DROP TABLE IF EXISTS table1") onCreate(db) } } -
AndroidManifest.xml注册代码:
<application ...> <provider android:name=".MyProvider" android:authorities="com.example.app.provider" android:enabled="true" android:exported="true" /> </application>
-
- 答案:
第9章 丰富你的程序,运用手机多媒体
重点知识
- 通知:
- 通知渠道:Android 8.0引入的概念,每条通知必须属于一个通知渠道。
- 创建通知渠道:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel("channel_id", "channel_name", NotificationManager.IMPORTANCE_DEFAULT) val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager manager.createNotificationChannel(channel) } - 发送通知:
val notification = NotificationCompat.Builder(this, "channel_id") .setContentTitle("Title") .setContentText("Text") .setSmallIcon(R.drawable.ic_notification) .build() val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager manager.notify(1, notification)
- 调用摄像头和相册:
- 调用摄像头拍照:
val intent = Intent("android.media.action.IMAGE_CAPTURE") intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri) startActivityForResult(intent, REQUEST_CODE) - 从相册中选择图片:
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) intent.addCategory(Intent.CATEGORY_OPENABLE) intent.type = "image/*" startActivityForResult(intent, REQUEST_CODE)
- 调用摄像头拍照:
- 播放多媒体文件:
- 播放音频:
val mediaPlayer = MediaPlayer() val assetManager = assets val fd = assetManager.openFd("music.mp3") mediaPlayer.setDataSource(fd.fileDescriptor, fd.startOffset, fd.length) mediaPlayer.prepare() mediaPlayer.start() - 播放视频:
val uri = Uri.parse("android.resource://$packageName/${R.raw.video}") videoView.setVideoURI(uri) videoView.start()
- 播放音频:
课后习题
单选题
-
在Android中,通知渠道是在哪个版本中引入的?答案:B
- A. Android 7.0
- B. Android 8.0
- C. Android 9.0
- D. Android 10.0
-
在Android中,调用系统相机拍照时,需要使用以下哪个Intent Action?答案:D
- A.
Intent.ACTION_VIEW - B.
Intent.ACTION_SEND - C.
Intent.ACTION_OPEN_DOCUMENT - D.
android.media.action.IMAGE_CAPTURE
- A.
-
在Android中,播放音频文件时,通常使用哪个类?答案:A
- A.
MediaPlayer - B.
VideoView - C.
AudioManager - D.
SoundPool
- A.
-
在Android中,通知的最小图标是通过哪个方法设置的?答案:C
- A.
setLargeIcon() - B.
setBigIcon() - C.
setSmallIcon() - D.
setIcon()
- A.
-
在Android中,
MediaPlayer的prepare()方法的作用是:答案:B- A. 开始播放
- B. 准备播放
- C. 暂停播放
- D. 停止播放
-
在Android中,
MediaPlayer的start()方法的作用是:答案:A- A. 开始播放
- B. 准备播放
- C. 暂停播放
- D. 停止播放
-
在Android中,
MediaPlayer的pause()方法的作用是:答案:C- A. 开始播放
- B. 准备播放
- C. 暂停播放
- D. 停止播放
-
在Android中,
MediaPlayer的stop()方法的作用是:答案:D- A. 开始播放
- B. 准备播放
- C. 暂停播放
- D. 停止播放
-
在Android中,
MediaPlayer的release()方法的作用是:答案:E- A. 开始播放
- B. 准备播放
- C. 暂停播放
- D. 停止播放
- E. 释放资源
-
在Android中,
MediaPlayer的isPlaying()方法的作用是:答案:F- A. 开始播放
- B. 准备播放
- C. 暂停播放
- D. 停止播放
- E. 释放资源
- F. 检查是否正在播放
-
在Android中,通知的最小图标是通过哪个方法设置的?答案:C
- A.
setLargeIcon() - B.
setBigIcon() - C.
setSmallIcon() - D.
setIcon()
- A.
-
在Android中,
MediaPlayer的prepare()方法的作用是:答案:B- A. 开始播放
- B. 准备播放
- C. 暂停播放
- D. 停止播放
-
在Android中,
MediaPlayer的start()方法的作用是:答案:A- A. 开始播放
- B. 准备播放
- C. 暂停播放
- D. 停止播放
-
在Android中,
MediaPlayer的pause()方法的作用是:答案:C- A. 开始播放
- B. 准备播放
- C. 暂停播放
- D. 停止播放
-
在Android中,
MediaPlayer的stop()方法的作用是:答案:D- A. 开始播放
- B. 准备播放
- C. 暂停播放
- D. 停止播放
多选题
-
在Android中,以下哪些是通知的组成部分?答案:A, B, C, D
- A. 通知渠道
- B. 通知内容
- C. 通知图标
- D. 通知ID
-
在Android中,以下哪些是播放多媒体文件的类?答案:A, B
- A.
MediaPlayer - B.
VideoView - C.
AudioManager - D.
SoundPool
- A.
-
在Android中,以下哪些是
MediaPlayer的常用方法?答案:A, B, C, D, E, F- A.
prepare() - B.
start() - C.
pause() - D.
stop() - E.
release() - F.
isPlaying()
- A.
-
在Android中,以下哪些是调用摄像头拍照的步骤?答案:A, B, C
- A. 创建Intent
- B. 设置输出路径
- C. 调用
startActivityForResult() - D. 调用
startActivity()
-
在Android中,以下哪些是播放视频的步骤?答案:A, B, C
- A. 创建
VideoView - B. 设置视频URI
- C. 调用
start() - D. 调用
pause()
- A. 创建
简答题
-
简述如何在Android中创建通知渠道。
- 答案:
- 在Android 8.0及以上版本中,需要创建通知渠道。通过
NotificationChannel类创建渠道,并通过NotificationManager注册渠道。
- 在Android 8.0及以上版本中,需要创建通知渠道。通过
- 答案:
-
简述如何在Android中调用系统相机拍照。
- 答案:
- 创建一个
Intent,指定android.media.action.IMAGE_CAPTURE作为action,并设置输出路径。通过startActivityForResult()启动相机应用。
- 创建一个
- 答案:
-
简述如何在Android中播放音频文件。
- 答案:
- 使用
MediaPlayer类播放音频文件。通过setDataSource()设置音频文件路径,调用prepare()方法准备播放,最后调用start()方法开始播放。
- 使用
- 答案:
综合题
- 创建一个名为
MainActivity的Activity,并在其中实现以下功能:- 创建一个通知渠道,并发送一个通知。
- 调用系统相机拍照,并将拍摄的照片显示在
ImageView中。 - 播放一个音频文件。
- 请写出
MainActivity的代码,以及相关布局文件。 - 答案:
-
MainActivity代码:
class MainActivity : AppCompatActivity() { private lateinit var imageView: ImageView private lateinit var mediaPlayer: MediaPlayer override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Create notification channel createNotificationChannel() // Take photo val takePhotoButton: Button = findViewById(R.id.takePhotoButton) takePhotoButton.setOnClickListener { val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) startActivityForResult(intent, REQUEST_CODE) } // Play audio val playAudioButton: Button = findViewById(R.id.playAudioButton) playAudioButton.setOnClickListener { mediaPlayer = MediaPlayer.create(this, R.raw.music) mediaPlayer.start() } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) { val bitmap = data?.extras?.get("data") as Bitmap imageView.setImageBitmap(bitmap) } } private fun createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel("channel_id", "channel_name", NotificationManager.IMPORTANCE_DEFAULT) val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager manager.createNotificationChannel(channel) val notification = NotificationCompat.Builder(this, "channel_id") .setContentTitle("Title") .setContentText("Text") .setSmallIcon(R.drawable.ic_notification) .build() manager.notify(1, notification) } } } -
activity_main布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <Button android:id="@+id/takePhotoButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Take Photo" /> <ImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="200dp" /> <Button android:id="@+id/playAudioButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Play Audio" /> </LinearLayout>
-
第10章 后台默默的劳动者,探究Service
重点知识
- Service:Android四大组件之一,用于后台执行长时间运行的任务。
- Service启动方式:
- startService:启动服务,服务可以在后台无限期运行。
- bindService:绑定服务,允许组件与服务进行交互。
- Service生命周期:
onCreate():服务创建时调用。onStartCommand():服务启动时调用。onDestroy():服务销毁时调用。
- 前台Service:
- 使用
startForeground()启动,显示通知图标。
- 使用
- 多线程编程:
- 继承Thread类:创建线程。
- 实现Runnable接口:创建线程。
- Handler:在子线程中更新UI。
- 协程:Kotlin语言的特性,用于异步操作。
课后习题
单选题
-
在Android中,
Service主要用于:答案:B- A. 用户界面
- B. 后台任务
- C. 数据存储
- D. 网络通信
-
在Android中,
Service的生命周期方法onCreate()的作用是:答案:A- A. 创建服务
- B. 启动服务
- C. 销毁服务
- D. 绑定服务
-
在Android中,
Service的生命周期方法onStartCommand()的作用是:答案:B- A. 创建服务
- B. 启动服务
- C. 销毁服务
- D. 绑定服务
-
在Android中,
Service的生命周期方法onDestroy()的作用是:答案:C- A. 创建服务
- B. 启动服务
- C. 销毁服务
- D. 绑定服务
-
在Android中,
Service的启动方式startService的作用是:答案:B- A. 创建服务
- B. 启动服务
- C. 销毁服务
- D. 绑定服务
-
在Android中,
Service的启动方式bindService的作用是:答案:D- A. 创建服务
- B. 启动服务
- C. 销毁服务
- D. 绑定服务
-
在Android中,
Service的startForeground()方法的作用是:答案:A- A. 将服务置于前台
- B. 将服务置于后台
- C. 创建服务
- D. 销毁服务
-
在Android中,
Service的stopSelf()方法的作用是:答案:C- A. 创建服务
- B. 启动服务
- C. 停止服务
- D. 绑定服务
-
在Android中,
Service的unbindService()方法的作用是:答案:D- A. 创建服务
- B. 启动服务
- C. 停止服务
- D. 解绑服务
-
在Android中,
Service的bindService()方法的作用是:答案:D- A. 创建服务
- B. 启动服务
- C. 停止服务
- D. 绑定服务
-
在Android中,
Service的startService()方法的作用是:答案:B- A. 创建服务
- B. 启动服务
- C. 停止服务
- D. 绑定服务
-
在Android中,
Service的onCreate()方法的作用是:答案:A- A. 创建服务
- B. 启动服务
- C. 停止服务
- D. 绑定服务
-
在Android中,
Service的onStartCommand()方法的作用是:答案:B- A. 创建服务
- B. 启动服务
- C. 停止服务
- D. 绑定服务
-
在Android中,
Service的onDestroy()方法的作用是:答案:C- A. 创建服务
- B. 启动服务
- C. 停止服务
- D. 绑定服务
-
在Android中,
Service的bindService()方法的作用是:答案:D- A. 创建服务
- B. 启动服务
- C. 停止服务
- D. 绑定服务
多选题
-
在Android中,以下哪些是
Service的生命周期方法?答案:A, B, C- A.
onCreate() - B.
onStartCommand() - C.
onDestroy() - D.
onPause()
- A.
-
在Android中,以下哪些是
Service的启动方式?答案:A, B- A.
startService() - B.
bindService() - C.
stopService() - D.
unbindService()
- A.
-
在Android中,以下哪些是多线程编程的方法?答案:A, B, C
- A. 继承
Thread类 - B. 实现
Runnable接口 - C. 使用
Handler - D. 使用
AsyncTask
- A. 继承
-
在Android中,以下哪些是
Service的特性?答案:A, B, C- A. 可以在后台运行
- B. 可以启动和停止
- C. 可以绑定和解绑
- D. 可以显示UI
-
在Android中,以下哪些是
Service的生命周期方法?答案:A, B, C- A.
onCreate() - B.
onStartCommand() - C.
onDestroy() - D.
onPause()
- A.
简答题
-
简述
Service的生命周期。- 答案:
onCreate():服务创建时调用。onStartCommand():服务启动时调用。onDestroy():服务销毁时调用。
- 答案:
-
简述
Service的启动方式。- 答案:
startService():启动服务,服务可以在后台无限期运行。bindService():绑定服务,允许组件与服务进行交互。
- 答案:
-
简述多线程编程的方法。
- 答案:
- 继承
Thread类:创建线程。 - 实现
Runnable接口:创建线程。 - 使用
Handler:在子线程中更新UI。
- 继承
- 答案:
综合题
- 创建一个名为
MyService的Service,并在其中实现一个后台任务,每隔5秒打印一次当前时间。请写出MyService的代码,以及在MainActivity中启动和停止MyService的代码。- 答案:
-
MyService代码:
class MyService : Service() { private lateinit var handler: Handler private lateinit var runnable: Runnable override fun onCreate() { super.onCreate() handler = Handler(Looper.getMainLooper()) runnable = object : Runnable { override fun run() { Log.d("MyService", "Current time: ${SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(Date())}") handler.postDelayed(this, 5000) } } handler.post(runnable) } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { return START_STICKY } override fun onDestroy() { super.onDestroy() handler.removeCallbacks(runnable) } override fun onBind(intent: Intent?): IBinder? { return null } } -
MainActivity代码:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val startServiceButton: Button = findViewById(R.id.startServiceButton) startServiceButton.setOnClickListener { val intent = Intent(this, MyService::class.java) startService(intent) } val stopServiceButton: Button = findViewById(R.id.stopServiceButton) stopServiceButton.setOnClickListener { val intent = Intent(this, MyService::class.java) stopService(intent) } } } -
activity_main布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <Button android:id="@+id/startServiceButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Start Service" /> <Button android:id="@+id/stopServiceButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Stop Service" /> </LinearLayout> -
AndroidManifest.xml注册代码:
<application ...> <service android:name=".MyService" /> </application>
-
- 答案:
第11章 看看精彩的世界,使用网络技术
重点知识
-
WebView:
- 用于在应用中嵌入网页。
- 示例:
val webView: WebView = findViewById(R.id.webView) webView.settings.javaScriptEnabled = true webView.webViewClient = WebViewClient() webView.loadUrl("https://www.example.com")
-
网络请求:
- HttpURLConnection:
val url = URL("https://www.example.com") val connection = url.openConnection() as HttpURLConnection connection.requestMethod = "GET" val input = connection.inputStream connection.disconnect() - OkHttp:
val client = OkHttpClient() val request = Request.Builder().url("https://www.example.com").build() val response = client.newCall(request).execute() val responseData = response.body?.string()
- HttpURLConnection:
-
数据解析:
-
XML解析:
- Pull解析:
val factory = XmlPullParserFactory.newInstance() val parser = factory.newPullParser() parser.setInput(StringReader(xmlData)) var eventType = parser.eventType while (eventType != XmlPullParser.END_DOCUMENT) { when (eventType) { XmlPullParser.START_TAG -> { when (parser.name) { "tag" -> { val value = parser.nextText() // 处理数据 } } } } eventType = parser.next() } - SAX解析:
val saxParser = SAXParserFactory.newInstance().newSAXParser() val handler = MyHandler() saxParser.parse(xmlData, handler)
- Pull解析:
-
JSON解析:
- JSONObject:
val jsonArray = JSONArray(jsonData) for (i in 0 until jsonArray.length()) { val jsonObject = jsonArray.getJSONObject(i) val id = jsonObject.getString("id") val name = jsonObject.getString("name") val version = jsonObject.getString("version") // 处理数据 } - GSON:
val type = object : TypeToken<List<MyObject>>() {}.type val list = Gson().fromJson<List<MyObject>>(jsonData, type)
- JSONObject:
-
-
Retrofit:
- 用于网络请求的库,基于OkHttp。
- 示例:
val retrofit = Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) .build() val service = retrofit.create(MyService::class.java) service.getData().enqueue(object : Callback<MyData> { override fun onResponse(call: Call<MyData>, response: Response<MyData>) { // 处理响应 } override fun onFailure(call: Call<MyData>, t: Throwable) { // 处理错误 } })
课后习题
单选题
-
在Android中,
WebView用于:答案:B- A. 显示图片
- B. 显示网页
- C. 播放视频
- D. 显示文本
-
在Android中,
HttpURLConnection用于:答案:B- A. 数据存储
- B. 网络请求
- C. UI显示
- D. 线程管理
-
在Android中,
OkHttp是一个:答案:B- A. 数据库
- B. 网络请求库
- C. UI框架
- D. 多线程库
-
在Android中,
Retrofit是一个:答案:B- A. 数据库
- B. 网络请求库
- C. UI框架
- D. 多线程库
-
在Android中,
WebView的loadUrl()方法的作用是:答案:B- A. 加载图片
- B. 加载网页
- C. 加载视频
- D. 加载文本
-
在Android中,
HttpURLConnection的getInputStream()方法的作用是:答案:B- A. 获取输出流
- B. 获取输入流
- C. 获取错误流
- D. 获取响应代码
-
在Android中,
OkHttp的newCall()方法的作用是:答案:B- A. 创建一个新的请求
- B. 创建一个新的调用
- C. 创建一个新的响应
- D. 创建一个新的连接
-
在Android中,
Retrofit的create()方法的作用是:答案:B- A. 创建一个新的请求
- B. 创建一个新的服务
- C. 创建一个新的响应
- D. 创建一个新的连接
-
在Android中,
WebView的setJavaScriptEnabled()方法的作用是:答案:B- A. 启用图片
- B. 启用JavaScript
- C. 启用视频
- D. 启用文本
-
在Android中,
HttpURLConnection的disconnect()方法的作用是:答案:D- A. 连接网络
- B. 发送请求
- C. 接收响应
- D. 断开连接
-
在Android中,
OkHttp的execute()方法的作用是:答案:B- A. 创建一个新的请求
- B. 执行请求
- C. 创建一个新的响应
- D. 创建一个新的连接
-
在Android中,
Retrofit的enqueue()方法的作用是:答案:B- A. 创建一个新的请求
- B. 异步执行请求
- C. 创建一个新的响应
- D. 创建一个新的连接
-
在Android中,
WebView的webViewClient的作用是:答案:B- A. 管理网页加载
- B. 管理网页客户端
- C. 管理网页请求
- D. 管理网页响应
-
在Android中,
HttpURLConnection的setRequestMethod()方法的作用是:答案:B- A. 设置请求头
- B. 设置请求方法
- C. 设置请求体
- D. 设置请求参数
-
在Android中,
OkHttp的Request.Builder()的作用是:答案:B- A. 创建一个新的请求
- B. 构建一个新的请求
- C. 创建一个新的响应
- D. 创建一个新的连接
多选题
-
在Android中,以下哪些是网络请求的库?答案:A, B, C
- A.
HttpURLConnection - B.
OkHttp - C.
Retrofit - D.
WebView
- A.
-
在Android中,以下哪些是数据解析的方式?答案:A, B
- A. XML解析
- B. JSON解析
- C. HTML解析
- D. CSS解析
-
在Android中,以下哪些是
WebView的特性?答案:A, B, C- A. 显示网页
- B. 支持JavaScript
- C. 支持HTML5
- D. 支持CSS3
-
在Android中,以下哪些是
HttpURLConnection的特性?答案:A, B, C- A. 发送GET请求
- B. 发送POST请求
- C. 获取响应数据
- D. 支持异步操作
-
在Android中,以下哪些是
OkHttp的特性?答案:A, B, C- A. 发送GET请求
- B. 发送POST请求
- C. 获取响应数据
- D. 支持异步操作
简答题
-
简述
WebView的用途。- 答案:
WebView用于在应用中嵌入网页,支持显示HTML内容和执行JavaScript。
- 答案:
-
简述
HttpURLConnection和OkHttp的区别。- 答案:
HttpURLConnection是Android官方提供的网络请求类,功能较为基础。OkHttp是一个第三方库,提供了更丰富的功能和更好的性能。
- 答案:
-
简述
Retrofit的作用。- 答案:
Retrofit是一个基于OkHttp的网络请求库,提供了更简洁的API和自动解析JSON的功能。
- 答案:
综合题
- 创建一个名为
MainActivity的Activity,并在其中实现以下功能:- 使用
WebView加载一个网页。 - 使用
HttpURLConnection发送一个GET请求,并将返回的数据显示在TextView中。 - 使用
OkHttp发送一个GET请求,并将返回的数据解析为JSON格式。 - 请写出
MainActivity的代码,以及相关布局文件。 - 答案:
-
MainActivity代码:
class MainActivity : AppCompatActivity() { private lateinit var webView: WebView private lateinit var textView: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) webView = findViewById(R.id.webView) textView = findViewById(R.id.textView) // Load web page webView.settings.javaScriptEnabled = true webView.webViewClient = WebViewClient() webView.loadUrl("https://www.example.com") // Send HTTP request using HttpURLConnection val sendRequestButton: Button = findViewById(R.id.sendRequestButton) sendRequestButton.setOnClickListener { thread { val url = URL("https://www.example.com") val connection = url.openConnection() as HttpURLConnection connection.requestMethod = "GET" val input = connection.inputStream val response = inputStreamToString(input) runOnUiThread { textView.text = response } } } // Send HTTP request using OkHttp val sendOkHttpRequestButton: Button = findViewById(R.id.sendOkHttpRequestButton) sendOkHttpRequestButton.setOnClickListener { thread { val client = OkHttpClient() val request = Request.Builder().url("https://www.example.com").build() val response = client.newCall(request).execute() val responseData = response.body?.string() if (responseData != null) { val jsonData = parseJSON(responseData) runOnUiThread { textView.text = jsonData } } } } } private fun inputStreamToString(input: InputStream): String { val reader = BufferedReader(InputStreamReader(input)) val sb = StringBuilder() reader.use { reader.forEachLine { sb.append(it) } } return sb.toString() } private fun parseJSON(responseData: String): String { val jsonArray = JSONArray(responseData) val sb = StringBuilder() for (i in 0 until jsonArray.length()) { val jsonObject = jsonArray.getJSONObject(i) val id = jsonObject.getString("id") val name = jsonObject.getString("name") val version = jsonObject.getString("version") sb.append("ID: $id, Name: $name, Version: $version\n") } return sb.toString() } } -
activity_main布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <WebView android:id="@+id/webView" android:layout_width="match_parent" android:layout_height="200dp" /> <TextView android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/sendRequestButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Send HTTP Request" /> <Button android:id="@+id/sendOkHttpRequestButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Send OkHttp Request" /> </LinearLayout>
-
- 使用
更多推荐



所有评论(0)