Files
final-exam/嵌入式系统/复习文档/Android应用开发基础.md
T

337 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
tags: [嵌入式系统, 复习, Android开发]
create time: 2026-06-10 11:11
---
# Android应用开发基础
## 概述
本文档覆盖Android应用开发的核心知识,包括分层架构、四大组件、Activity生命周期、数据存储、UI布局、权限管理和常用设计模式。这是嵌入式系统课程中移动终端开发部分的复习重点。
## 正文
### 1. Android分层架构
Android系统采用分层架构设计,从底层到顶层分为四层:
```mermaid
graph TD
A["Applications"] --> B["Application Framework"]
B --> C["Libraries / Android Runtime"]
C --> D["Linux Kernel"]
style A fill:#4fc3f7
style B fill:#81d4fa
style C fill:#b3e5fc
style D fill:#ffcc80
```
| 层级 | 组成 | 说明 |
|------|------|------|
| **Applications** | 短信、电话、浏览器、第三方App | 用户直接使用的应用 |
| **Application Framework** | Activity Manager, Content Provider, Resource Manager, Notification Manager | 提供构建应用的基础API |
| **Libraries / Runtime** | SQLite, OpenGL, WebKit, Media Framework, Dalvik/ART | 系统库和运行时环境 |
| **Linux Kernel** | 驱动、内存管理、进程管理、网络栈 | 底层硬件抽象和系统服务 |
> [!tip] Dalvik vs ART
> - **Dalvik**:Android 4.4之前使用,基于JIT(Just-In-Time)编译
> - **ART**:Android 5.0开始替代Dalvik,使用AOT(Ahead-Of-Time)编译,运行更快但安装更慢
### 2. 四大组件
Android应用由四大核心组件构成:
#### 2.1 Activity(活动)
Activity代表一个**用户界面屏幕**,是用户与应用交互的主要入口。
```java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
```
#### 2.2 Service(服务)
Service在**后台**运行,没有用户界面。适合执行长时间运行的操作(如音乐播放、文件下载)。
两种启动方式:
- **Started Service**:通过startService()启动,独立运行
- **Bound Service**:通过bindService()绑定,提供客户端-服务器接口
#### 2.3 ContentProvider(内容提供者)
ContentProvider用于**跨应用数据共享**。它封装了数据访问接口,其他应用通过ContentResolver来查询和修改数据。
```java
// 在AndroidManifest.xml中注册
<provider
android:name=".MyContentProvider"
android:authorities="com.example.myprovider"
android:exported="true" />
```
> [!question] 为什么需要ContentProvider而不是直接共享数据库?
> ContentProvider提供了统一的数据访问接口和权限控制机制。直接共享数据库会暴露数据结构细节,且难以控制访问权限。
#### 2.4 BroadcastReceiver(广播接收器)
BroadcastReceiver用于接收和响应**系统或应用广播**,实现组件间的松耦合通信。
配置方式有两种:
**XML静态注册**:
```xml
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
```
**代码动态注册**:
```java
IntentFilter filter = new IntentFilter("com.example.MY_ACTION");
registerReceiver(new MyReceiver(), filter);
```
### 3. Activity生命周期
Activity的生命周期是Android开发的基础知识点:
```mermaid
stateDiagram-v2
[*] --> Created
Created --> Started: onCreate -> onStart
Started --> Running: onResume
Running --> Paused: onPause
Paused --> Running: onResume
Paused --> Stopped: onStop
Stopped --> Started: onRestart -> onStart
Stopped --> Created: onDestroy
Running --> Stopped: onStop
Paused --> Created: onDestroy
Created --> [*]: onDestroy
note right of Created: Activity created
note right of Started: Visible but not focused
note right of Running: Foreground, interactive
note right of Paused: Partially obscured
note right of Stopped: Fully hidden
```
| 生命周期方法 | 调用时机 | 说明 |
|-------------|----------|------|
| onCreate() | Activity首次创建 | 初始化界面、绑定数据 |
| onStart() | Activity变为可见 | 准备显示 |
| onResume() | Activity获得焦点 | 可与用户交互 |
| onPause() | Activity失去焦点 | 保存临时数据(秒级) |
| onStop() | Activity完全不可见 | 释放资源 |
| onDestroy() | Activity被销毁 | 最终清理 |
| onRestart() | 从Stopped重新启动 | 不会直接到onCreate |
> [!warning] onPause()中不要做耗时操作
> onPause()执行完毕后,新的Activity才会启动。如果在onPause()中做网络请求或大量数据处理,会导致界面切换卡顿。耗时操作应该放到onStop()或异步任务中。
### 4. Intent数据传递
Intent是Android中组件间通信的核心机制,用于启动Activity、Service和发送广播。
**传递数据的两种方式**:
**Serializable**(Java标准序列化):
```java
// 发送端
Intent intent = new Intent(this, TargetActivity.class);
intent.putExtra("user", (Serializable) userObj);
startActivity(intent);
// 接收端
User user = (User) getIntent().getSerializableExtra("user");
```
**Parcelable**(Android特有序列化,性能更好):
```java
// 发送端
intent.putExtra("user", (Parcelable) userObj);
// 接收端
User user = getIntent().getParcelableExtra("user");
```
| 比较 | Serializable | Parcelable |
|------|-------------|------------|
| 性能 | 慢(使用反射) | 快(手动实现) |
| 实现 | 简单(实现接口即可) | 复杂(需实现writeToParcel) |
| 用途 | 临时存储、简单对象 | Activity间频繁传递 |
| 开销 | 产生大量临时对象 | 内存开销小 |
### 5. startActivityForResult
当一个Activity需要从另一个Activity**获取返回数据**时,使用startActivityForResult:
```java
// 启动方
Intent intent = new Intent(this, SecondActivity.class);
startActivityForResult(intent, REQUEST_CODE);
// 接收返回数据
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
String result = data.getStringExtra("result");
// 处理返回数据
}
}
// 被启动方设置返回数据
Intent resultIntent = new Intent();
resultIntent.putExtra("result", "hello from second");
setResult(RESULT_OK, resultIntent);
finish();
```
### 6. SQLite数据类型
Android内置SQLite数据库,支持以下5种数据类型:
| 数据类型 | 说明 |
|----------|------|
| NULL | 空值 |
| INTEGER | 整数 |
| REAL | 浮点数 |
| TEXT | 文本字符串 |
| BLOB | 二进制大对象 |
> [!warning] SQLite没有VARCHAR类型
> SQLite使用动态类型系统,TEXT类型可以存储任意长度的字符串,不需要指定VARCHAR(n)。但创建表时写VARCHAR也是合法的(会被忽略长度约束)。
### 7. UI布局
Android支持多种布局方式:
| 布局类型 | 特点 | 适用场景 |
|----------|------|----------|
| **LinearLayout** | 线性排列(水平/垂直) | 简单的行列排列 |
| **RelativeLayout** | 相对定位 | 复杂的相对位置关系 |
| **FrameLayout** | 层叠排列,后面的元素覆盖前面 | 重叠界面、帧动画 |
**SimpleAdapter**用于为ListView等列表控件提供数据:
```java
// 数据源:List<Map<String, Object>>
List<Map<String, Object>> data = new ArrayList<>();
Map<String, Object> item = new HashMap<>();
item.put("title", "标题");
item.put("image", R.drawable.icon);
data.add(item);
// 创建适配器
SimpleAdapter adapter = new SimpleAdapter(
this,
data,
R.layout.list_item,
new String[]{"title", "image"}, // 数据键
new int[]{R.id.tvTitle, R.id.ivIcon} // 视图ID
);
listView.setAdapter(adapter);
```
> [!question] SimpleAdapter的数据映射List&lt;Map&gt;中,Map的key和value分别对应什么?
> key是字符串类型的字段名(如"title"),value是该字段的值(如"标题"文本)。适配器通过key从Map中取值,然后绑定到对应的视图控件上。
### 8. 权限管理
Android 7.0将权限分为四种保护级别:
| 权限级别 | 说明 | 安装行为 |
|----------|------|----------|
| **normal** | 低风险权限(如网络访问) | 自动授予 |
| **dangerous** | 高风险权限(如摄像头、位置) | 需要用户确认 |
| **signature** | 只有与应用签名相同的应用才能获得 | 自动授予 |
| **signatureOrSystem** | 签名相同或系统应用才能获得 | 自动授予 |
权限声明方式(AndroidManifest.xml):
```xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
```
> [!warning] Android 6.0+运行时权限
> 从Android 6.0开始,dangerous权限需要在运行时动态申请,而不仅仅在Manifest中声明。但signature和normal权限仍然在安装时自动授予。
### 9. SharedPreferences
SharedPreferences是Android提供的轻量级键值对存储机制:
```java
// 保存数据
SharedPreferences prefs = getSharedPreferences("mydata", MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("username", "admin");
editor.putInt("age", 25);
editor.apply(); // 异步写入
// 读取数据
String name = prefs.getString("username", "default");
int age = prefs.getInt("age", 0);
```
> [!warning] 默认不能跨应用共享
> MODE_PRIVATE表示该SharedPreferences文件只有当前应用可以访问。如果需要跨应用共享数据,应该使用ContentProvider。
### 10. res vs assets
| 比较 | res | assets |
|------|-----|--------|
| 引用方式 | 通过R.java自动生成的ID | 通过AssetManager按文件名访问 |
| 子目录 | 有结构化子目录(drawable, layout等) | 无结构,可自由组织 |
| 自动优化 | 编译时会被压缩/优化 | 原样保留 |
| 文件名限制 | 只能用小写字母、数字、下划线 | 无限制 |
```java
// res资源引用
setContentView(R.layout.activity_main);
ImageView iv = findViewById(R.id.imageView);
iv.setImageResource(R.drawable.icon);
// assets资源访问
InputStream is = getAssets().open("data/config.json");
```
### 11. 单例模式
单例模式确保一个类只有一个实例:
```java
public class DatabaseHelper {
private static volatile DatabaseHelper instance;
// 私有构造函数,防止外部实例化
private DatabaseHelper() {
// 初始化数据库
}
public static DatabaseHelper getInstance() {
if (instance == null) {
synchronized (DatabaseHelper.class) {
if (instance == null) {
instance = new DatabaseHelper();
}
}
}
return instance;
}
}
```
> [!tip] 双重检查锁定(Double-Checked Locking)
> 单例模式中使用volatile + synchronized实现线程安全的懒加载。volatile防止指令重排序,synchronized保证只创建一次实例。
## 关联笔记
- [[嵌入式系统/试题册/index|试题册索引]]