likes
comments
collection
share

深入浅出 Android ContentProvider系列 (二)

作者站长头像
站长
· 阅读数 33

深入浅出 Android ContentProvider系列 (二)

ContentProvider 是 Android 中用于数据共享和跨进程通信的重要组件,通过统一的接口和标准化的 URI 访问方式,提供了安全、封装和高效的数据操作。接下来,我们将更详细地介绍 ContentProvider 的高级特性和常见使用场景。

1. 高级特性和常见使用场景

1.1. 使用 ContentObserver 监听数据变化

ContentObserver 用于监听 ContentProvider 中数据的变化,当数据发生改变时会收到通知。这样可以实现实时数据同步或更新 UI。

示例:实现 ContentObserver

创建一个 ContentObserver 并注册它来监听数据变化:

public class MyContentObserver extends ContentObserver {
    public MyContentObserver(Handler handler) {
        super(handler);
    }

    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        // 数据变化处理逻辑
    }

    @Override
    public void onChange(boolean selfChange, Uri uri) {
        super.onChange(selfChange, uri);
        // 处理特定 URI 的数据变化
    }
}

在需要监听的地方注册 ContentObserver:

Handler handler = new Handler();
MyContentObserver observer = new MyContentObserver(handler);
getContentResolver().registerContentObserver(ExampleProvider.CONTENT_URI, true, observer);

注销 ContentObserver 以避免内存泄漏:

getContentResolver().unregisterContentObserver(observer);

1.2. 数据同步

ContentProvider 可以与 SyncAdapter 结合,实现自动数据同步。例如,当远程服务器上的数据发生变化时,可以通过 SyncAdapter 同步到本地数据库,并通过 ContentProvider 提供的数据接口进行访问。

示例:实现 SyncAdapter

创建 SyncAdapter:

public class ExampleSyncAdapter extends AbstractThreadedSyncAdapter {
    public ExampleSyncAdapter(Context context, boolean autoInitialize) {
        super(context, autoInitialize);
    }

    @Override
    public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
        // 同步逻辑
        // 更新数据后通过 provider.notifyChange 通知变化
    }
}

配置 SyncAdapter 和 ContentProvider 结合:

<sync-adapter
    android:contentAuthority="com.example.provider"
    android:accountType="com.example.account"
    android:userVisible="true"
    android:supportsUploading="true"
    android:allowParallelSyncs="false"
    android:isAlwaysSyncable="true" />

1.3. 批量操作

ContentProvider 支持批量操作,通过 applyBatch 方法可以一次性执行多个操作,提高效率。

示例:批量操作

创建 ContentProvider 中的批量操作方法:

@Override
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) throws OperationApplicationException {
    final SQLiteDatabase db = databaseHelper.getWritableDatabase();
    db.beginTransaction();
    try {
        ContentProviderResult[] results = super.applyBatch(operations);
        db.setTransactionSuccessful();
        return results;
    } finally {
        db.endTransaction();
    }
}

使用批量操作:

ArrayList<ContentProviderOperation> operations = new ArrayList<>();
operations.add(ContentProviderOperation.newInsert(CONTENT_URI)
        .withValue("name", "Example1")
        .build());
operations.add(ContentProviderOperation.newInsert(CONTENT_URI)
        .withValue("name", "Example2")
        .build());
try {
    getContentResolver().applyBatch("com.example.provider", operations);
} catch (RemoteException | OperationApplicationException e) {
    e.printStackTrace();
}

1.4. 权限控制

为了保护敏感数据,ContentProvider 可以通过声明权限来控制数据访问。

示例:声明权限

AndroidManifest.xml 中声明权限:

<permission android:name="com.example.provider.READ" android:protectionLevel="signature" />
<permission android:name="com.example.provider.WRITE" android:protectionLevel="signature" />
<provider
    android:name=".ExampleProvider"
    android:authorities="com.example.provider"
    android:exported="true"
    android:readPermission="com.example.provider.READ"
    android:writePermission="com.example.provider.WRITE" />

在 ContentProvider 中检查权限:

@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection,
                    @Nullable String[] selectionArgs, @Nullable String sortOrder) {
    if (getContext().checkCallingOrSelfPermission("com.example.provider.READ") == PackageManager.PERMISSION_DENIED) {
        throw new SecurityException("Permission denied");
    }
    // 执行查询操作
}

2. ContentProvider 的设计总结

ContentProvider 作为 Android 中跨应用数据共享的重要机制,具备以下设计优势:

  1. 标准化接口:提供了统一的数据访问接口,简化了跨进程数据操作的实现。
  2. 安全性:通过权限控制和 URI 权限授予,确保数据访问的安全性。
  3. 数据封装:将数据操作逻辑封装在 ContentProvider 中,提高了代码的模块化和可维护性。
  4. 批量操作和事务:支持批量操作和事务处理,提高了数据操作的效率和一致性。
  5. 通知机制:通过 ContentObserver 实现数据变化的实时监听和通知,便于实现数据同步和 UI 更新。

通过合理设计和使用 ContentProvider,开发者可以构建高效、安全、可扩展的 Android 应用,实现复杂的数据交互和共享需求。


欢迎点赞|关注|收藏|评论,您的肯定是我创作的动力
转载自:https://juejin.cn/post/7393311009685733395
评论
请登录