Android开发四大组件详解
Android应用程序的四大组件是Android架构的核心,它们分别是:
- Activity(活动) - 用户界面组件
- Service(服务) - 后台处理组件
- BroadcastReceiver(广播接收器) - 消息通信组件
- ContentProvider(内容提供者) - 数据共享组件
1. Activity(活动)
作用说明
Activity是Android应用中的用户界面组件,每个Activity代表一个屏幕界面。就像一本书的每一页,用户可以在不同的Activity之间切换,完成不同的操作。
生命周期
Activity有完整的生命周期,主要包括:
onCreate()
- 创建时调用onStart()
- 开始可见时调用onResume()
- 获得焦点时调用onPause()
- 失去焦点时调用onStop()
- 不可见时调用onDestroy()
- 销毁时调用
核心代码示例
java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化界面组件
Button loginButton = findViewById(R.id.login_button);
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 跳转到另一个Activity
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
}
});
}
@Override
protected void onResume() {
super.onResume();
// Activity重新获得焦点时的操作
Log.d("MainActivity", "Activity已恢复");
}
@Override
protected void onPause() {
super.onPause();
// Activity失去焦点时保存数据
saveUserData();
}
private void saveUserData() {
// 保存用户数据的逻辑
}
}
2. Service(服务)
作用说明
Service是在后台运行的组件,即使用户切换到其他应用,Service仍然可以继续工作。就像手机的音乐播放器,即使你在聊微信,音乐依然在后台播放。
服务类型
- 前台服务 - 用户可感知,如音乐播放
- 后台服务 - 用户不可感知,如数据同步
- 绑定服务 - 与其他组件绑定使用
核心代码示例
java
public class MusicService extends Service {
private MediaPlayer mediaPlayer;
@Override
public void onCreate() {
super.onCreate();
// 服务创建时初始化
mediaPlayer = new MediaPlayer();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 服务启动时执行的操作
String action = intent.getStringExtra("action");
if ("PLAY".equals(action)) {
playMusic();
} else if ("PAUSE".equals(action)) {
pauseMusic();
}
// 返回START_STICKY表示服务被杀死后会自动重启
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// 返回null表示这是一个启动服务,不是绑定服务
return null;
}
private void playMusic() {
try {
mediaPlayer.setDataSource("music_file_path");
mediaPlayer.prepare();
mediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
}
private void pauseMusic() {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mediaPlayer != null) {
mediaPlayer.release();
}
}
}
// 在Activity中启动服务
public class MainActivity extends AppCompatActivity {
private void startMusicService() {
Intent intent = new Intent(this, MusicService.class);
intent.putExtra("action", "PLAY");
startService(intent);
}
}
3. BroadcastReceiver(广播接收器)
作用说明
BroadcastReceiver用于接收系统或应用发送的广播消息。就像收音机接收电台信号一样,当系统发生某些事件(如电池电量低、网络连接变化)时,BroadcastReceiver可以接收到这些消息并做出响应。
广播类型
- 系统广播 - 系统发送的广播(如开机完成、电池电量变化)
- 自定义广播 - 应用自己发送的广播
- 有序广播 - 按优先级顺序接收
- 无序广播 - 同时接收
核心代码示例
java
public class NetworkReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 接收到广播时的处理逻辑
String action = intent.getAction();
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
// 网络状态发生变化
ConnectivityManager cm = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
// 网络已连接
Toast.makeText(context, "网络已连接", Toast.LENGTH_SHORT).show();
// 可以开始网络请求
syncData(context);
} else {
// 网络已断开
Toast.makeText(context, "网络已断开", Toast.LENGTH_SHORT).show();
}
}
}
private void syncData(Context context) {
// 网络连接后同步数据的逻辑
}
}
// 在Activity中注册广播接收器
public class MainActivity extends AppCompatActivity {
private NetworkReceiver networkReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 动态注册广播接收器
networkReceiver = new NetworkReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(networkReceiver, filter);
}
@Override
protected void onDestroy() {
super.onDestroy();
// 取消注册广播接收器
if (networkReceiver != null) {
unregisterReceiver(networkReceiver);
}
}
// 发送自定义广播
private void sendCustomBroadcast() {
Intent intent = new Intent("com.example.CUSTOM_ACTION");
intent.putExtra("message", "这是自定义广播消息");
sendBroadcast(intent);
}
}
4. ContentProvider(内容提供者)
作用说明
ContentProvider用于在不同应用之间共享数据。就像图书馆的管理员,负责管理数据的存取,其他应用可以通过标准的接口来访问这些数据,而不需要知道数据的具体存储方式。
主要功能
- 数据封装和安全访问
- 跨应用数据共享
- 统一的数据访问接口
- 数据权限控制
核心代码示例
java
public class ContactProvider extends ContentProvider {
private static final String AUTHORITY = "com.example.contactprovider";
private static final String TABLE_NAME = "contacts";
// URI匹配器
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
private static final int CONTACTS = 1;
private static final int CONTACT_ID = 2;
static {
uriMatcher.addURI(AUTHORITY, TABLE_NAME, CONTACTS);
uriMatcher.addURI(AUTHORITY, TABLE_NAME + "/#", CONTACT_ID);
}
private SQLiteDatabase database;
@Override
public boolean onCreate() {
// 初始化数据库
ContactDBHelper dbHelper = new ContactDBHelper(getContext());
database = dbHelper.getWritableDatabase();
return database != null;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// 查询数据
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(TABLE_NAME);
switch (uriMatcher.match(uri)) {
case CONTACTS:
// 查询所有联系人
break;
case CONTACT_ID:
// 查询特定ID的联系人
String id = uri.getLastPathSegment();
queryBuilder.appendWhere("_id = " + id);
break;
default:
throw new IllegalArgumentException("未知URI: " + uri);
}
return queryBuilder.query(database, projection, selection,
selectionArgs, null, null, sortOrder);
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// 插入数据
long rowId = database.insert(TABLE_NAME, null, values);
if (rowId > 0) {
Uri newUri = ContentUris.withAppendedId(
Uri.parse("content://" + AUTHORITY + "/" + TABLE_NAME), rowId);
getContext().getContentResolver().notifyChange(newUri, null);
return newUri;
}
throw new SQLException("插入数据失败: " + uri);
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// 更新数据
int count = 0;
switch (uriMatcher.match(uri)) {
case CONTACTS:
count = database.update(TABLE_NAME, values, selection, selectionArgs);
break;
case CONTACT_ID:
String id = uri.getLastPathSegment();
count = database.update(TABLE_NAME, values,
"_id = " + id + (!TextUtils.isEmpty(selection) ?
" AND (" + selection + ")" : ""), selectionArgs);
break;
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// 删除数据
int count = 0;
switch (uriMatcher.match(uri)) {
case CONTACTS:
count = database.delete(TABLE_NAME, selection, selectionArgs);
break;
case CONTACT_ID:
String id = uri.getLastPathSegment();
count = database.delete(TABLE_NAME,
"_id = " + id + (!TextUtils.isEmpty(selection) ?
" AND (" + selection + ")" : ""), selectionArgs);
break;
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case CONTACTS:
return "vnd.android.cursor.dir/vnd.example.contact";
case CONTACT_ID:
return "vnd.android.cursor.item/vnd.example.contact";
default:
throw new IllegalArgumentException("未知URI: " + uri);
}
}
}
// 在其他应用中使用ContentProvider
public class MainActivity extends AppCompatActivity {
private void queryContacts() {
Uri uri = Uri.parse("content://com.example.contactprovider/contacts");
ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(uri, null, null, null, null);
if (cursor != null) {
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex("name"));
String phone = cursor.getString(cursor.getColumnIndex("phone"));
Log.d("Contact", "姓名: " + name + ", 电话: " + phone);
}
cursor.close();
}
}
private void insertContact() {
Uri uri = Uri.parse("content://com.example.contactprovider/contacts");
ContentValues values = new ContentValues();
values.put("name", "张三");
values.put("phone", "13800138000");
Uri newUri = getContentResolver().insert(uri, values);
if (newUri != null) {
Toast.makeText(this, "联系人添加成功", Toast.LENGTH_SHORT).show();
}
}
}
四大组件总结
组件间的协作关系
- Activity 负责用户界面交互
- Service 在后台处理长时间运行的任务
- BroadcastReceiver 处理系统和应用间的消息通信
- ContentProvider 提供数据共享机制
实际应用场景举例
- 音乐播放器应用 :
- Activity:显示播放界面、歌曲列表
- Service:后台播放音乐
- BroadcastReceiver:接收耳机插拔、来电等事件
- ContentProvider:共享音乐文件信息给其他应用
配置文件注册
所有组件都需要在AndroidManifest.xml中注册:
xml
<application>
<!-- Activity注册 -->
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Service注册 -->
<service android:name=".MusicService" />
<!-- BroadcastReceiver注册 -->
<receiver android:name=".NetworkReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<!-- ContentProvider注册 -->
<provider
android:name=".ContactProvider"
android:authorities="com.example.contactprovider"
android:exported="true" />
</application>