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

11 KiB
Raw Blame History

tags, create time
tags create time
嵌入式系统
复习
Android开发
2026-06-10 11:11

Android应用开发基础

概述

本文档覆盖Android应用开发的核心知识,包括分层架构、四大组件、Activity生命周期、数据存储、UI布局、权限管理和常用设计模式。这是嵌入式系统课程中移动终端开发部分的复习重点。

正文

1. Android分层架构

Android系统采用分层架构设计,从底层到顶层分为四层:

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代表一个用户界面屏幕,是用户与应用交互的主要入口。

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来查询和修改数据。

// 在AndroidManifest.xml中注册
<provider
    android:name=".MyContentProvider"
    android:authorities="com.example.myprovider"
    android:exported="true" />

[!question] 为什么需要ContentProvider而不是直接共享数据库? ContentProvider提供了统一的数据访问接口和权限控制机制。直接共享数据库会暴露数据结构细节,且难以控制访问权限。

2.4 BroadcastReceiver(广播接收器)

BroadcastReceiver用于接收和响应系统或应用广播,实现组件间的松耦合通信。

配置方式有两种:

XML静态注册:

<receiver android:name=".MyReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

代码动态注册:

IntentFilter filter = new IntentFilter("com.example.MY_ACTION");
registerReceiver(new MyReceiver(), filter);

3. Activity生命周期

Activity的生命周期是Android开发的基础知识点:

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标准序列化):

// 发送端
Intent intent = new Intent(this, TargetActivity.class);
intent.putExtra("user", (Serializable) userObj);
startActivity(intent);

// 接收端
User user = (User) getIntent().getSerializableExtra("user");

Parcelable(Android特有序列化,性能更好):

// 发送端
intent.putExtra("user", (Parcelable) userObj);

// 接收端
User user = getIntent().getParcelableExtra("user");
比较 Serializable Parcelable
性能 慢(使用反射) 快(手动实现)
实现 简单(实现接口即可) 复杂(需实现writeToParcel)
用途 临时存储、简单对象 Activity间频繁传递
开销 产生大量临时对象 内存开销小

5. startActivityForResult

当一个Activity需要从另一个Activity获取返回数据时,使用startActivityForResult:

// 启动方
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等列表控件提供数据:

// 数据源: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<Map>中,Map的key和value分别对应什么? key是字符串类型的字段名(如"title"),value是该字段的值(如"标题"文本)。适配器通过key从Map中取值,然后绑定到对应的视图控件上。

8. 权限管理

Android 7.0将权限分为四种保护级别:

权限级别 说明 安装行为
normal 低风险权限(如网络访问) 自动授予
dangerous 高风险权限(如摄像头、位置) 需要用户确认
signature 只有与应用签名相同的应用才能获得 自动授予
signatureOrSystem 签名相同或系统应用才能获得 自动授予

权限声明方式(AndroidManifest.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提供的轻量级键值对存储机制:

// 保存数据
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等) 无结构,可自由组织
自动优化 编译时会被压缩/优化 原样保留
文件名限制 只能用小写字母、数字、下划线 无限制
// 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. 单例模式

单例模式确保一个类只有一个实例:

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保证只创建一次实例。

关联笔记