ContentProvider
顾名思义就是内容提供者,它支持不同的进程间的通信、数据传输。
ContentProvider 是 Android 中的一个组件,用于管理和提供应用程序的数据给其他应用程序。它提供了一种标准化的方式,允许应用程序通过 URI 来访问数据,而不必了解数据的具体存储方式。
工作原理
数据访问接口: ContentProvider 为其他应用程序提供了一种标准化的数据访问接口。其他应用程序可以通过 ContentResolver对象来访问 ContentProvider中的数据,而不必了解数据的存储方式。
URI 标识数据: ContentProvider 使用 URI 来标识和访问数据。每个 ContentProvider 都会定义一个或多个 URI,用于标识不同类型和不同位置的数据。其他应用程序通过这些 URI 来访问 ContentProvider 中的数据。
数据存储: ContentProvider 可以管理各种类型的数据,包括关系型数据库、文件系统、网络数据等。它通常会封装对这些数据的访问和操作,并提供统一的接口给其他应用程序使用。
权限控制: ContentProvider 可以通过权限控制来限制对数据的访问。它可以定义哪些应用程序有权访问数据,并通过 AndroidManifest.xml 文件中的权限声明来进行控制。
多进程支持: ContentProvider 支持多进程访问,可以在不同的应用程序和进程之间共享数据。它可以在不同的进程中运行,并提供线程安全的数据访问接口。
用法
1.引入 provider.class
,这里面写入远程调用方法的逻辑,比如CRUD。
package cn.dfx0.hooook.utils;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class MyContentProvider extends ContentProvider {
public static List<ContentValues> data = new ArrayList<>();
// 定义 ContentProvider 的 URI
public static final Uri CONTENT_URI = Uri.parse("content://cn.dfx0.hooook.provider/data");
@Override
public boolean onCreate() {
// 初始化 ContentProvider
return true;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
// 实现查询数据的方法
// 这里可以查询数据并返回 Cursor
return null;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
// 实现获取 MIME 类型的方法
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
data.add(values);
// 实现插入数据的方法
return uri;
}
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
// 实现删除数据的方法
return 0;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
// 实现更新数据的方法
return 0;
}
}
2.修改xml配置文件
<application ...>
<provider
android:name=".utils.MyContentProvider"
android:authorities="cn.dfx0.hooook.provider"
android:exported="true" />
</application>
3.在另外的进程里面调用上面的方法即可数据共享
// 使用 ContentResolver 插入数据
ContentResolver resolver = context[0].getContentResolver();
resolver.insert("content://cn.dfx0.hooook.provider/data", values);
4.同时 在Xposed模块中获取当前应用的context可以用以下代码实现:
XposedHelpers.findAndHookMethod(Application.class, "attach", Context.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
context[0] = (Context) param.args[0]; //context[0]就是获取的当前窗体
}
});
}
跨进程修改值图例: