目录
一、Activity:用户界面的核心
Activity 是 Android 应用的核心组成部分之一,主要负责展示用户界面,响应用户的交互操作。每个 Activity 通常对应一个独立的屏幕,用户可以在多个 Activity 之间进行切换。
1.功能
- 作为应用的 UI 界面。
- 处理用户交互,响应用户的点击、输入等操作。
- 管理 Activity 的生命周期,控制界面的启动、暂停、销毁等状态。
2.生命周期
2.1生命周期方法
- onCreate():Activity 被创建时调用,通常用于进行初始化操作,比如设置布局、初始化 UI 元素、绑定数据等。
- onStart():Activity 正在启动,并即将变为可见状态,但此时还没有获取焦点。
- onResume():Activity 开始与用户交互,并成为用户当前操作的界面。
- onPause():Activity 正在停止与用户交互,通常用户切换到另一个 Activity 时会调用,需在此释放一些非必要的资源。
- onStop():Activity 不再可见,进入后台,通常此时应释放所有资源,以防止内存泄露。
- onRestart():Activity 从不可见状态重新进入可见状态(从后台切回前台)时调用。
- onDestroy():Activity 被销毁时调用,进行清理工作,释放所有资源。
2.2生命周期流程图
3.启动模式
3.1 标准模式 (standard)
- 默认模式,每次启动一个 Activity,都会创建一个新的实例。
- 应用场景:一般用于不需要重复检查 Activity 实例的普通页面。
3.2 单顶模式 (singleTop)
- 如果任务栈的顶部已经存在该 Activity 的实例,则不会重新创建实例,而是复用栈顶的实例。
- 应用场景:常用于详情页面、设置页面等多次打开,但不希望重复创建实例的场景。
3.3 单任务模式 (singleTask)
- 在任务栈中只会存在一个实例,如果任务栈中已经存在该 Activity,则复用此实例,并清除其上的所有 Activity。
- 应用场景:用于需要保证某个 Activity 在任务栈中始终唯一的场景,如主页面、导航页面。
3.4 单实例模式 (singleInstance)
- 在整个系统中只会存在一个该 Activity 的实例,无论是哪个应用启动此 Activity,都会复用同一个实例。
- 应用场景:用于特殊应用场景,比如独占全局的 Activity,例如系统的拨号界面等。
4. Activity之间的通信
Activity 之间的通信主要通过 Intent 实现,Intent 是 Android 中用来启动组件(如 Activity、Service)和传递数据的重要机制。
4.1 启动另一个 Activity
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent); // 启动 SecondActivity
4.2 启动并传递数据
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("key", "value");
startActivity(intent);
在 SecondActivity 中接收数据:
String value = getIntent().getStringExtra("key");
4.3 返回结果
有时我们希望启动一个 Activity,并从中获取返回结果。可以使用 startActivityForResult() 来启动,并在 onActivityResult() 中接收返回的数据。
启动并期待返回结果:
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivityForResult(intent, REQUEST_CODE);
在 SecondActivity 中返回结果:
Intent intent = new Intent();
intent.putExtra("result", "value");
setResult(RESULT_OK, intent);
finish();
在 MainActivity 中接收返回结果:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
String result = data.getStringExtra("result");
// 处理结果
}
}
5. Activity的UI管理
Activity 是 UI 展示的核心,主要通过 XML 布局文件和代码相结合的方式管理界面。每个 Activity 通常对应一个布局文件,布局文件中定义了 UI 组件的位置和样式,代码中处理这些组件的行为。
5.1 设置布局
在 onCreate() 方法中通过 setContentView() 设置布局:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // 设置对应的布局文件
}
5.2 访问 UI 元素
通过 findViewById() 访问布局中的 UI 组件:
Button button = findViewById(R.id.myButton);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 按钮点击事件
}
});
6.注意事项
- 管理好 Activity 的生命周期,确保资源的合理分配与回收,避免内存泄漏。
- 注意横竖屏切换时生命周期的变化,需要妥善处理。
二、Service:后台处理任务
Service 是 Android 的后台组件,用于在不需要用户界面交互的情况下执行长时间运行的任务,例如音乐播放、下载文件等。Service 是在后台运行的,不会直接与用户交互。
1.功能
- 执行后台操作,如网络请求、播放音频、同步数据等。
- 可以与 Activity 进行交互,但没有用户界面。
2. Service的分类
Android 中 Service 分为三种主要类型,每种类型适合不同的应用场景。
2.1 普通服务(Started Service)
Started Service 是通过调用 startService() 方法启动的。服务一旦启动,即使启动它的 Activity 被销毁,服务仍然可以在后台继续运行,直到调用 stopSelf() 或 stopService() 来停止服务。
- 启动方式:startService() 或 Context.startForegroundService()
- 停止方式:调用 stopSelf() 或 stopService()。
- 典型场景:如音乐播放、文件下载等需要持续运行的任务。
Intent intent = new Intent(this, MyService.class);
startService(intent); // 启动服务
2.2 绑定服务(Bound Service)
Bound Service 允许其他组件通过绑定的方式与服务交互。通过 bindService() 方法启动并绑定服务,组件可以与服务进行通信。服务在所有绑定的客户端解绑后会自动销毁。
- 启动方式:bindService()
- 停止方式:当所有绑定的客户端解绑后,服务会自动销毁。
- 典型场景:如客户端与服务端的交互,或者需要与应用频繁交互的任务。
Intent intent = new Intent(this, MyService.class);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); // 绑定服务
2.3 前台服务(Foreground Service)
Foreground Service 是一种特殊的 Started Service,它会在通知栏显示一个通知,以提高优先级,避免系统在资源紧张时优先关闭它。
- 启动方式:Context.startForegroundService(),并在服务中调用 startForeground() 方法显示通知。
- 典型场景:如音乐播放器在后台播放音乐、导航应用持续提供GPS导航等。
Intent intent = new Intent(this, MyService.class);
startForegroundService(intent); // 启动前台服务
在 Service 中调用 startForeground():
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText("Running in the background")
.setSmallIcon(R.drawable.ic_service)
.build();
startForeground(1, notification); // 显示前台服务的通知
3. Service的生命周期
Service 的生命周期方法与 Activity 类似,但其核心不同点在于 Service 是后台运行,不涉及用户交互。
3.1 Started Service的生命周期
onCreate():服务创建时调用,仅调用一次,通常用于初始化服务资源。
onStartCommand():每次通过 startService() 启动服务时调用,执行具体任务的逻辑。返回值决定了系统在服务终止后的行为。
- START_STICKY:服务终止后会自动重启,适用于需要持续运行的服务(如音乐播放、下载服务)。
- START_NOT_STICKY:服务终止后不会自动重启,适用于不需要持续运行的短期任务。
- START_REDELIVER_INTENT:服务终止后会自动重启,并重新传递最后一个 Intent,适用于需要继续处理上次未完成任务的情况。
onDestroy():服务被销毁时调用,用于清理资源。
3.2 Bound Service的生命周期
onCreate():服务创建时调用。
onBind():服务被绑定时调用,返回一个 IBinder 实例,用于客户端与服务通信。
onUnbind():当所有客户端解绑时调用。
onDestroy():服务销毁时调用。
3. Service与线程
Service 本身运行在主线程中,任何长时间的操作(如网络请求、文件下载)应在另一个线程如果直接在 Service 中执行耗时任务,可能会阻塞 UI 线程,导致应用无响应(ANR)。因此,开发者通常使用线程池、Handler 或者 IntentService 来处理异步任务。
3.1 使用线程池 (ThreadPoolExecutor) 来处理异步任务
线程池 是一种高效的异步任务处理方式,可以管理多个并发任务。通过创建线程池,开发者可以限制同时执行的任务数量,并优化性能。
public class MyService extends Service {
private ExecutorService executorService;
@Override
public void onCreate() {
super.onCreate();
// 创建线程池
executorService = Executors.newFixedThreadPool(3); // 设置最多3个并发线程
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 向线程池提交任务
executorService.execute(new Runnable() {
@Override
public void run() {
// 在后台执行耗时任务,比如文件下载
performLongRunningTask();
}
});
return START_STICKY;
}
private void performLongRunningTask() {
// 模拟长时间操作
try {
Thread.sleep(5000); // 模拟耗时任务
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (executorService != null) {
executorService.shutdown(); // 关闭线程池
}
}
@Override
public IBinder onBind(Intent intent) {
return null; // 如果不是 Bound Service 返回null
}
}
3.2 使用 HandlerThread 和 Handler 来处理异步任务
HandlerThread 是一个带有 Looper 的线程,用于处理与 Handler 的消息通信。它特别适合在后台执行异步任务,并且提供了消息调度的能力。
public class MyService extends Service {
private HandlerThread handlerThread;
private Handler handler;
@Override
public void onCreate() {
super.onCreate();
// 创建一个HandlerThread
handlerThread = new HandlerThread("MyServiceThread");
handlerThread.start();
// 使用HandlerThread的Looper创建Handler
handler = new Handler(handlerThread.getLooper());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 向Handler发送任务
handler.post(new Runnable() {
@Override
public void run() {
// 在后台线程中执行任务
performLongRunningTask();
}
});
return START_STICKY;
}
private void performLongRunningTask() {
// 模拟长时间操作
try {
Thread.sleep(5000); // 模拟耗时任务
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
super.onDestroy();
handlerThread.quit(); // 退出HandlerThread
}
@Override
public IBinder onBind(Intent intent) {
return null; // 如果不是 Bound Service 返回null
}
}
3.3 使用 IntentService 处理异步任务
IntentService 是 Service 的一个子类,它专门用于处理异步请求,并且是自带一个工作线程来处理耗时任务。任务处理完毕后,IntentService 会自动停止。
public class MyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
// 处理任务的逻辑
performLongRunningTask();
}
private void performLongRunningTask() {
// 模拟长时间操作
try {
Thread.sleep(5000); // 模拟耗时任务
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
启动 IntentService:
Intent intent = new Intent(this, MyIntentService.class);
startService(intent);
4. 注意事项
- 在服务中执行长时间运行的任务时,应该考虑资源管理,避免占用过多电量或内存。
- 一般情况下,Foreground Service 优先级最高,普通 Service优先级较低,容易被系统回收。如果需要后台运行的 Service 在用户看不见时不被系统杀死,可以使用Foreground Service,显示一个持续的通知。
三、BroadcastReceiver:处理广播消息
BroadcastReceiver 是 Android 中用于接收系统或应用发送的广播消息的组件。广播机制是 Android 中用于跨应用或跨进程通信的方式,应用可以通过广播发送和接收消息。
1. 功能
- 接收系统广播,如电量低、网络状态变化等。
- 接收应用内广播,用于不同模块之间的消息传递。
2. BroadcastReceiver的工作原理
当某个事件发生时,系统或应用会通过发送一个 Intent 来广播该事件。所有注册了相关广播事件的BroadcastReceiver都可以接收到这个广播,并在广播到达时执行预定义的任务。
基本工作流程如下:
- 广播发送方:通过sendBroadcast()、sendOrderedBroadcast()或sendStickyBroadcast()方法发送广播。
- 广播接收方:通过注册的BroadcastReceiver接收相应的广播。
- 处理逻辑:在BroadcastReceiver的onReceive()方法中,处理接收到的广播消息。
3. BroadcastReceiver的注册方式
3.1 静态注册
静态注册的 BroadcastReceiver 是在AndroidManifest.xml中声明的,通常用于接收设备启动、安装应用、网络变化等系统级广播,即使应用未启动,仍然可以接收到广播。
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
3.2 动态注册
动态注册的BroadcastReceiver是在代码中通过registerReceiver()方法进行的,适用于应用在运行期间才需要监听的事件。
public class MainActivity extends AppCompatActivity {
private MyBroadcastReceiver myReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myReceiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(myReceiver, filter); // 动态注册广播接收器
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myReceiver); // 动态注册的广播接收器需及时解除
}
}
4. BroadcastReceiver的生命周期
BroadcastReceiver的生命周期很短,通常在广播到来时会触发onReceive()方法,处理完成后即终止。广播接收器并不需要一直运行。
- onReceive():当广播到达时调用,可以根据广播的内容执行相应的操作。
5. 广播的收发
Android 提供了多种广播收发形式,分别适合不同的应用场景。广播通常通过Intent进行传递,接收者可以注册特定的广播接收器(BroadcastReceiver)来监听广播事件。
5.1 标准广播(Normal Broadcast)
标准广播是通过sendBroadcast()方法发送的。它是并发执行的,所有匹配的BroadcastReceiver同时接收广播,不保证接收顺序。
发送标准广播:
Intent intent = new Intent("com.example.CUSTOM_BROADCAST");
sendBroadcast(intent); // 发送标准广播
接收标准广播:通过动态或静态方式注册广播接收器来接收广播。
- 动态注册:
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 处理广播
Toast.makeText(context, "Received broadcast!", Toast.LENGTH_SHORT).show();
}
}
public class MainActivity extends AppCompatActivity {
private MyBroadcastReceiver myReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myReceiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter("com.example.CUSTOM_BROADCAST");
registerReceiver(myReceiver, filter); // 动态注册广播接收器
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myReceiver); // 动态注册的广播需要解除注册
}
}
- 静态注册:
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="com.example.CUSTOM_BROADCAST"/>
</intent-filter>
</receiver>
5.2 有序广播(Ordered Broadcast)
有序广播是通过sendOrderedBroadcast()方法发送的,它允许多个接收器按优先级顺序接收广播。高优先级的接收器可以截断广播或修改广播数据,广播按照优先级从高到低传递。
发送有序广播:
Intent intent = new Intent("com.example.CUSTOM_ORDERED_BROADCAST");
sendOrderedBroadcast(intent, null); // 发送有序广播
接收有序广播:接收有序广播的BroadcastReceiver可以通过setResultData()等方法修改广播数据,并决定是否继续将广播传递给下一个接收器。
public class MyOrderedBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String resultData = getResultData(); // 获取前一个接收器设置的结果数据
setResultData("Modified by receiver!"); // 修改广播内容
Toast.makeText(context, "Ordered broadcast received", Toast.LENGTH_SHORT).show();
}
}
通过priority属性设置广播接收器的优先级,值越高优先级越高。
<receiver android:name=".MyOrderedBroadcastReceiver">
<intent-filter>
<action android:name="com.example.CUSTOM_ORDERED_BROADCAST"/>
<priority android:value="100"/>
</intent-filter>
</receiver>
5.3 静态广播
静态广播是通过在AndroidManifest.xml文件中声明广播接收器实现的。静态注册的广播接收器可以在应用未启动的情况下接收广播,常用于监听设备启动、电池状态等系统广播。
<receiver android:name=".BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
BOOT_COMPLETED 是设备启动完成后系统发送的广播,静态注册的接收器可以在设备重启后自动执行操作。
6. 本地广播(LocalBroadcast)
在Android中,也可以使用LocalBroadcastManager发送本地广播。相比于全局广播,本地广播只在应用内部传递,效率更高,并且不会泄露数据给其他应用,安全性更好。
使用本地广播:
1.注册本地广播接收器:
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
IntentFilter filter = new IntentFilter("com.example.LOCAL_BROADCAST");
localBroadcastManager.registerReceiver(myReceiver, filter);
2.发送本地广播:
Intent localIntent = new Intent("com.example.LOCAL_BROADCAST");
LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
3.解除注册:
LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver);
7. 监听系统广播
Android 系统会在特定的事件发生时发送系统广播,应用程序可以通过注册广播接收器来监听这些事件。
7.1 监听网络变更广播
ConnectivityManager.CONNECTIVITY_ACTION是网络连接状态变化时系统发送的广播。当设备从离线变为在线或网络状态发生变化时,应用可以接收此广播并执行相应操作。
定义一个网络广播的接收:
public class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
Toast.makeText(context, "Network Connected", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Network Disconnected", Toast.LENGTH_SHORT).show();
}
}
}
动态注册广播接收器:
@Override
protected void onStart() {
super.onStart();
// 创建广播接收器
NetworkChangeReceiver networkChangeReceiver = new NetworkChangeReceiver();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
// 注册接收器
registerReceiver(networkChangeReceiver, filter);
}
@Override
protected void onStop() {
super.onStop();
// 注销接收器
unregisterReceiver(networkChangeReceiver);
}
7.2监听分钟到达广播
ACTION_TIME_TICK是系统每分钟发送一次的广播,常用于在应用中处理与时间相关的功能,比如更新 UI 上的时间显示。
定义一个分钟广播的接收器:
public class TimeTickReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Minute passed", Toast.LENGTH_SHORT).show();
}
}
由于ACTION_TIME_TICK是频繁触发的广播,在Android 8.0及之后,静态注册无法接收此类广播。必须使用动态注册的方式。
@Override
protected void onStart() {
super.onStart();
TimeTickReceiver timeTickReceiver = new TimeTickReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_TIME_TICK);
registerReceiver(timeTickReceiver, filter);
}
@Override
protected void onStop() {
super.onStop();
unregisterReceiver(timeTickReceiver);
}
7.3 监听系统闹钟广播
AlarmManager可以设置定时任务,定时到达后系统会发送广播进行唤醒。通过设置闹钟,我们可以使用AlarmManager来调度任务,并通过BroadcastReceiver监听定时任务触发的广播。
定义一个闹钟广播的接收器:
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 处理闹钟到达事件
Toast.makeText(context, "Alarm received!", Toast.LENGTH_SHORT).show();
}
}
设置定时器:
// 从系统服务中获取闹钟管理器
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// 创建一个广播事件的意图
Intent intent = new Intent(this, AlarmReceiver.class);
// 创建一个用于广播的延迟意图
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
// 设置一个5秒后触发的闹钟
long triggerTime = System.currentTimeMillis() + 5000;
alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
静态注册广播接收器:
<receiver android:name=".AlarmReceiver"/>
7.4 监听开机启动广播
BOOT_COMPLETED是设备启动后系统发送的广播,用于执行设备重启后的任务(如启动服务、初始化数据等)。需要注意,接收此广播必须在 AndroidManifest.xml 中静态注册,并且应用需要声明权限。
定义一个分钟广播的接收器:
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
// 处理设备启动完成后的操作
Toast.makeText(context, "Device booted", Toast.LENGTH_SHORT).show();
}
}
}
静态注册广播接收器:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name=".BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
8. 权限与安全性
某些广播,尤其是系统广播,需要在AndroidManifest.xml中声明权限。此外,广播的安全性也很重要。如果广播包含敏感信息或需要保护,应该避免使用全局广播。相反,使用本地广播或通过限制广播权限来保护广播内容。
四、ContentProvider:应用间共享数据
ContentProvider 是 Android 提供的用于跨应用共享数据的组件。通过 ContentProvider,一个应用可以提供数据供其他应用访问,并控制数据的权限和访问方式。系统内置了很多 ContentProvider,比如访问联系人、媒体文件等。
1. 功能
- 在应用间共享数据,提供标准的接口供其他应用访问。
- 支持 CRUD(增删改查)操作,允许其他应用按需读取、更新、删除数据。
2. ContentProvider的结构
ContentProvider提供了操作数据的基本接口,主要包括以下方法:
- onCreate():初始化数据库,通常在这个方法中你会创建或打开SQLite 数据库。
- query():返回一个Cursor对象,供查询数据使用。
- insert():插入新的数据,返回新插入行的URI。
- update():更新已有数据,根据条件返回更新的行数。
- delete():删除数据,根据条件删除并返回受影响的行数。
- getType():返回MIME类型,表示该URI对应的是单条数据还是多条数据。
3. ContentProvider的注册方式
ContentProvider必须在AndroidManifest.xml中静态注册。系统在需要的时候会自动初始化该ContentProvider。
<provider
android:name=".MyContentProvider"
android:authorities="com.example.provider"
android:exported="true" />
- android:authorities:定义该ContentProvider的授权名,其他应用通过这个名称访问它。
- android:exported:如果设置为true,表示允许其他应用访问;设置为false时,只能供本应用访问。
4. 访问ContentProvider的数据
应用要访问ContentProvider提供的数据,需要通过ContentResolver来执行增删改查操作。
- query():从内容提供器中检索数据。
- insert():向内容提供器中插入新的数据行。
- update():修改内容提供器中的现有数据。
- delete():从内容提供器中删除数据。
5. ContentProvider中的URI机制
在ContentProvider中,数据是通过URI来定位的。每个ContentProvider都有一个唯一的 URI,它由以下几个部分组成:
content://<authority>/<path>/<id>
- content://:URI 的协议部分,固定为content://。
- <authority>:表示该 ContentProvider 的授权名,通常是应用的包名。
- <path>:表示数据的路径,通常是表名。
- <id>:可选项,指定要操作的数据的ID。
在操作数据时,不同的URI可以用于标识特定的数据集或单条数据,区分全表查询和单行查询。
6. 常见的系统 ContentProvider
Android系统自带了一些常见的ContentProvider,开发者可以通过这些ContentProvider访问系统级数据。
6.1 通讯录(ContactsProvider)
- URI:content://contacts/
- 用途:访问设备中的联系人信息。
Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
6.2 媒体库(MediaStore)
- URI:content://media/external/
- 用途:访问设备中的音频、视频、图片等媒体文件。
Cursor cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
6.3 日历(CalendarProvider)
- URI:content://com.android.calendar/
- 用途:访问设备中的日历事件和日程。
Cursor cursor = getContentResolver().query(CalendarContract.Events.CONTENT_URI, null, null, null, null);
7. 安全性与权限控制
由于ContentProvider可能涉及多个应用的数据共享,安全性问题非常重要。为了保证数据的安全,Android提供了以下方式来保护ContentProvider。
7.1 声明权限:
可以通过声明权限来控制谁能够访问ContentProvider。在AndroidManifest.xml中,你可以通过android:permission属性来限制对 ContentProvider 的访问。
<provider
android:name=".MyContentProvider"
android:authorities="com.example.provider"
android:permission="com.example.permission.ACCESS_PROVIDER" />
7.2 自定义权限:
开发者可以在AndroidManifest.xml中定义自定义权限:
<permission android:name="com.example.permission.ACCESS_PROVIDER" android:protectionLevel="normal" />
标签:Service,广播,Intent,Activity,组件,四大,Android,intent,public From: https://blog.csdn.net/m0_75208773/article/details/143154875