2984 字
15 分钟
Android 期末复习题与答案

本文整理了 Android 课程期末复习题,覆盖 Intent、四大组件、广播、数据存储、ContentProvider、Fragment、SQLite、Service 等核心知识点,并给出完整参考答案。

一、论述题#

1. 论述 Intent 的两种类型:显式 Intent 和隐式 Intent 的定义,并说明它们分别应用于哪些场合#

显式 Intent(Explicit Intent): 通过直接指定目标组件的类名(Component)来启动组件。需要明确知道目标 Activity / Service 的具体类。

Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);

应用场合:用于同一个应用内部组件之间的跳转,开发者明确知道要启动哪个组件。

隐式 Intent(Implicit Intent): 不指定具体组件名,而是通过 Action、Category、Data 等信息描述要执行的操作,由系统根据 IntentFilter 匹配合适的组件。

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.baidu.com"));
startActivity(intent);

应用场合:用于跨应用调用,例如调用系统的拨号、浏览器、相机、地图、发送短信等功能,或者调用第三方应用提供的能力。


2. Android 采用分层结构,从高到低分为几层,用途分别是什么?#

Android 系统从高到低分为 4 层

层级名称用途
第 1 层应用程序层(Applications)系统自带和第三方安装的应用,如电话、短信、浏览器、相机等
第 2 层应用程序框架层(Application Framework)为开发者提供构建应用的各种 API,如 Activity Manager、Window Manager、Content Provider、View System 等
第 3 层系统运行库层(Libraries + Android Runtime)C/C++ 库(如 SQLite、OpenGL、WebKit、SSL)及 Android 运行时(核心库 + Dalvik/ART 虚拟机)
第 4 层Linux 内核层(Linux Kernel)提供系统底层服务:进程管理、内存管理、驱动程序(显示、相机、Wi-Fi、音频等)、安全机制

3. 论述广播在 Android 中的作用,说明广播的两种注册方式有什么不同,应用场合分别是哪些?#

广播的作用: 广播(Broadcast)是 Android 中实现组件间、应用间通信的一种机制。系统或应用可以发出广播消息,其他注册了对应广播接收器(BroadcastReceiver)的组件可以接收并处理这些消息,从而实现解耦的事件通知(如开机完成、电量变化、网络变化、来电等)。

两种注册方式

比较项静态注册(清单注册)动态注册(代码注册)
注册位置AndroidManifest.xml<receiver> 标签在代码中调用 registerReceiver()
生命周期应用未启动也能接收(常驻)跟随注册组件的生命周期,需要 unregisterReceiver() 注销
应用场合接收系统级、长期性的广播,如开机启动、网络变化(注:Android 8.0 之后大多数隐式广播被禁止静态注册)接收特定时段、特定页面关心的广播,如 Activity 运行期间监听电量、自定义业务事件

4. 论述 Android 中常见的数据存储有哪些?分别有什么特点#

Android 提供 5 种主要的数据存储方式:

  1. SharedPreferences(轻量级键值存储)

    • 特点:基于 XML 文件,以 key-value 方式保存,只能存储基本数据类型(boolean、int、float、long、String)。适合保存用户设置、配置参数等少量数据。
  2. 文件存储(Internal / External Storage)

    • 特点:以 IO 流的形式将数据存储到内部或外部存储。内部存储是私有的,外部存储(SD 卡)可被其他应用读取。适合存储较大的文本、二进制文件。
  3. SQLite 数据库

    • 特点:轻量级关系型数据库,支持标准 SQL 语法,事务、索引。适合存储结构化、数据量较大的数据,如联系人、聊天记录。
  4. ContentProvider(内容提供者)

    • 特点:为不同应用之间共享数据提供统一接口,通过 URI 访问。适合跨应用共享数据,如系统通讯录、媒体库。
  5. 网络存储(Network Storage)

    • 特点:将数据存储到远程服务器(云端),通过 HTTP / WebService 等方式访问。适合需要多端同步的数据。

5. ContentProvider 和 ContentResolver 应用程序间实现共享数据是如何实现的?#

实现原理

  • ContentProvider(内容提供者):数据提供方应用继承 ContentProvider 类,重写 onCreate()query()insert()update()delete()getType() 六个方法,将自己内部的数据(通常是 SQLite)通过统一的 URI 暴露出来,并在 AndroidManifest.xml 中通过 <provider> 标签注册,指定 authorities

  • ContentResolver(内容解析者):数据使用方应用通过 Context.getContentResolver() 获取 ContentResolver 实例,调用其 query()insert()update()delete() 方法,传入对应的 URI(格式为 content://authorities/path)。

工作流程

  1. 提供方在 ContentProvider 中实现数据的增删改查逻辑。
  2. 使用方通过 ContentResolver + URI 发起请求。
  3. 系统根据 URI 的 authorities 找到对应的 ContentProvider。
  4. 调用 ContentProvider 中对应的方法,返回结果(如 Cursor)给使用方。

这样就在两个独立应用进程之间实现了安全、统一的数据共享。


6. 分析 Fragment 与 Activity 的联系#

联系

  1. 依附关系:Fragment 必须依附于 Activity 才能存在和显示,不能独立运行。一个 Activity 可以包含多个 Fragment,一个 Fragment 也可以在多个 Activity 中复用。

  2. 生命周期关联:Fragment 的生命周期受所依附 Activity 的生命周期影响。Activity 暂停,Fragment 也暂停;Activity 销毁,Fragment 也销毁。但 Fragment 比 Activity 多了几个生命周期方法(如 onAttach()onCreateView()onActivityCreated()onDetach())。

  3. 通信方式

    • Activity 调用 Fragment:通过 FragmentManager.findFragmentById() 找到 Fragment 实例,然后调用其公开方法。
    • Fragment 调用 Activity:通过 getActivity() 获取宿主 Activity 引用。
    • Fragment 之间:通常通过宿主 Activity 中转,或使用接口回调、ViewModel、EventBus 等方式通信。
  4. UI 构成:Fragment 拥有自己的布局和 UI,可被动态添加、移除、替换到 Activity 的视图容器中,实现灵活的界面组合(特别适合平板等大屏设备)。

  5. 管理:Fragment 由 Activity 中的 FragmentManager 管理,通过 FragmentTransaction 进行添加(add)、移除(remove)、替换(replace)等操作。


二、程序设计题#

1. MainActivity 与 SecondActivity 数据传递#

MainActivity.java

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn1 = findViewById(R.id.btn1);
Button btn2 = findViewById(R.id.btn2);
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "欢迎进入考试系统", Toast.LENGTH_SHORT).show();
}
});
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("number", "20230001");
intent.putExtra("name", "张三");
intent.putExtra("age", 20);
startActivity(intent);
}
});
}
}

SecondActivity.java

public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
TextView tvShow = findViewById(R.id.tv_show);
Intent intent = getIntent();
String number = intent.getStringExtra("number");
String name = intent.getStringExtra("name");
int age = intent.getIntExtra("age", 0);
tvShow.setText("学号:" + number + "\n姓名:" + name + "\n年龄:" + age);
}
}

2. 两数相乘并显示结果#

MainActivity.java

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ss); // 布局文件 ss.xml
final EditText ed1 = findViewById(R.id.ed_number1);
final EditText ed2 = findViewById(R.id.ed_number2);
final TextView tv = findViewById(R.id.tv);
Button btn = findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String s1 = ed1.getText().toString();
String s2 = ed2.getText().toString();
if (s1.isEmpty() || s2.isEmpty()) {
tv.setText("请输入两个数字");
return;
}
double num1 = Double.parseDouble(s1);
double num2 = Double.parseDouble(s2);
double result = num1 * num2;
tv.setText("结果:" + result);
}
});
}
}

3. SQLite 帮助类 MyHelper#

public class MyHelper extends SQLiteOpenHelper {
public MyHelper(Context context) {
super(context, "library.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
String createTable = "create table book("
+ "id integer primary key,"
+ "name text,"
+ "price real)";
db.execSQL(createTable);
// 插入两条记录
db.execSQL("insert into book(id, name, price) values(?, ?, ?)",
new Object[]{1, "钢铁是怎样炼成的", 38.5});
db.execSQL("insert into book(id, name, price) values(?, ?, ?)",
new Object[]{2, "告别内耗", 59.8});
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// 升级时的处理
}
}

使用:在 Activity 中

MyHelper helper = new MyHelper(this);
SQLiteDatabase db = helper.getWritableDatabase(); // 触发 onCreate

三、界面设计题(参考 XML 布局)#

题目原图未提供,给出一个典型登录界面 XML 模板供参考。

<?xml version="1.0" encoding="utf-8"?>
<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="20dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="用户登录"
android:textSize="24sp"
android:gravity="center"
android:layout_marginBottom="30dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="用户名:"
android:textSize="16sp"/>
<EditText
android:id="@+id/et_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入用户名"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="密 码:"
android:textSize="16sp"/>
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:hint="请输入密码"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登录"
android:layout_marginRight="20dp"/>
<Button
android:id="@+id/btn_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="取消"/>
</LinearLayout>
</LinearLayout>

四、程序分析题#

1. 广播注册与发送的代码补全#

public class MainActivity extends Activity {
private MyReceiver receiver;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
receiver = new MyReceiver();
IntentFilter filter = new IntentFilter("YourAction");
registerReceiver(receiver, filter); // 注册广播监听
}
public void myRegist(View view) {
Intent intent = new Intent("YourAction");
Bundle bundle = new Bundle();
bundle.putString("way", "我的注册方式"); // 放入 String
bundle.putDouble("number", 10.8); // 放入 double
intent.putExtras(bundle);
sendBroadcast(intent); // 发送广播
}
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver); // 注销广播
}
}

2. MyReceiver 程序注释#

public class MyReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("YourAction"))
// 注释1:判断接收到的广播 Action 是否为 "YourAction",过滤目标广播
{
String data = intent.getStringExtra("class");
// 注释2:从 intent 中取出键为 "class" 的 String 数据
Log.d("MyReceiver", "我的班级是:" + data);
// 注释3:在 Logcat 中以 debug 级别打印取出的数据,便于调试
Bundle bundle = new Bundle();
bundle.putString("order", "尽快报到");
// 注释4:创建 Bundle 并放入键 "order"、值 "尽快报到" 的字符串数据
setResultExtras(bundle);
// 注释5:将 bundle 作为有序广播的结果数据回传给下一个接收者或发送者
}
}
}

3. Intent 传值代码补全#

public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button1).setOnClickListener(new OnClickListener() { // 1. 添加动作监听
public void onClick(View arg0) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class); // 2. 跳转
intent.putExtra("id", 110); // 3. 添加 int 类型数据
intent.putExtra("scores", 98.5); // 4. 添加 double 类型数据
startActivity(intent); // 5. 传递并启动 Activity
}
});
}
}

4. MyHelper 三个方法的功能#

public class MyHelper extends SQLiteOpenHelper {
public MyHelper(Context context) {
super(context, "courseSelect.db", null, 1);
}
// 方法1:构造方法。调用父类 SQLiteOpenHelper 的构造,指定数据库名为
// "courseSelect.db",使用默认游标工厂(null),数据库版本号为 1。
@Override
public void onCreate(SQLiteDatabase db) {
String createTable = "create table student"
+ "(id integer primary key autoincrement,name text,number text,gender text,age integer)";
db.execSQL(createTable);
}
// 方法2:当数据库**首次创建**时被调用。
// 通过 SQL 语句创建 student 表,包含 id(主键自增)、name、number、gender、age 五个字段。
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
// 方法3:当数据库**版本升级**(构造方法中传入的版本号高于旧版本)时被调用,
// 用于对旧表进行结构升级(如删除旧表、新建表、添加字段等迁移操作)。
}

5. Service 程序阅读题#

public class MyService extends Service {
public IBinder onBind(Intent arg0) { return null; }
public void onCreate() {
super.onCreate();
Log.d("Service", "onCreate: 服务已创建");
}
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("Service", "onStartCommand: 服务正在运行");
return START_STICKY;
}
public void onDestroy() {
super.onDestroy();
Log.d("Service", "onDestroy: 服务已停止");
}
}

(1)使用 startService() 启动后 LogCat 显示的内容

第一次启动时(服务还未创建)显示:

onCreate: 服务已创建
onStartCommand: 服务正在运行

如果再次调用 startService(),由于服务实例已存在,不会再调用 onCreate,只会调用 onStartCommand,输出:

onStartCommand: 服务正在运行

(2)继承 Service 后必须重写的方法

必须重写 onBind(Intent intent) 方法(这是 Service 类中唯一的抽象方法)。

(3)onDestroy 方法何时执行?

在以下情况下被调用:

  • 通过 stopService() 显式停止服务;
  • 服务内部调用 stopSelf() 自己停止;
  • 系统因内存紧张被强制回收时;
  • 应用进程被结束时。

(4)Service 可以执行耗时操作吗?为什么?

不可以直接在 Service 中执行耗时操作。 因为 Service 默认运行在主线程(UI 线程)中,长时间耗时操作会阻塞主线程,导致 ANR(Application Not Responding)。 如果需要执行耗时操作,应当在 Service 内部开启子线程(new Thread 或 HandlerThread),或者使用 IntentService(已内置工作线程)。

(5)MyService 类需要在 AndroidManifest.xml 中注册吗?为什么?

需要注册。 Service 是 Android 四大组件之一,所有四大组件(Activity、Service、BroadcastReceiver、ContentProvider)都必须在清单文件中声明,否则系统无法识别和启动该组件,运行时会抛出异常。注册示例:

<service android:name=".MyService" />

复习要点速记#

  • 四大组件:Activity、Service、BroadcastReceiver、ContentProvider,都需要在清单文件注册
  • Intent 传值:基本类型用 putExtra,复杂数据用 Bundle + putExtras
  • 广播注册:静态(清单)/ 动态(代码 + 必须注销)。
  • SQLite:继承 SQLiteOpenHelper,重写 onCreateonUpgrade
  • Service:默认主线程,耗时操作要开子线程;必须重写 onBind
  • Fragment:必须依附 Activity,通过 FragmentManager 管理。

考试加油 💪

Android 期末复习题与答案
https://xubbbbbb.top/posts/android-final-exam/
作者
Xubbbbbb
发布于
2026-06-24
许可协议
CC BY-NC-SA 4.0