当前位置:   article > 正文

深入分析 Android ContentProvider (二)

深入分析 Android ContentProvider (二)

深入分析 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 的数据变化
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

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

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

注销 ContentObserver 以避免内存泄漏:

getContentResolver().unregisterContentObserver(observer);
  • 1

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 通知变化
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

配置 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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

使用批量操作:

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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在 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");
    }
    // 执行查询操作
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2. ContentProvider 的设计总结

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

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

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

欢迎点赞|关注|收藏|评论,您的肯定是我创作的动力

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/892092
推荐阅读
相关标签
  

闽ICP备14008679号