Android能否在运行时更新ContentProvider的URI?
问题描述
我是Android开发新手,发现AndroidManifest.xml中声明的MyContentProvider会在应用启动时由系统创建,而非通过我的代码实例化,因此无法获取该Java对象的引用。我希望能在运行时修改这个ContentProvider,请问这是否可行?
AndroidManifest.xml 配置
<provider android:name=".MyContentProvider" android:authorities="com.i.sticker_admin.mycontentprovider" android:enabled="true" android:exported="true" android:readPermission="com.whatsapp.sticker.READ" />
尝试过的代码(MainActivity.java)
MyContentProvider myContentProvider = new MyContentProvider(); ArrayList<String> newUris = new ArrayList<>(); myContentProvider.addNewUris(newUris);
这段代码本应向MyContentProvider的内部变量添加信息,但并未生效,因为它创建了新的实例而非修改清单中声明的那个。
可行方案
直接获取系统创建的ContentProvider实例不符合Android设计规范,但可以通过以下方式实现运行时修改需求:
利用静态变量/单例共享状态
在MyContentProvider内部定义静态变量存储需要修改的数据,并提供静态方法供外部调用:public class MyContentProvider extends ContentProvider { private static final ArrayList<String> sUris = new ArrayList<>(); @Override public boolean onCreate() { return true; } public static void addNewUris(ArrayList<String> newUris) { // 注意线程安全,多线程场景建议用CopyOnWriteArrayList synchronized (sUris) { sUris.addAll(newUris); } } // 在query/insert等方法中直接使用sUris }然后在MainActivity中直接调用静态方法:
ArrayList<String> newUris = new ArrayList<>(); newUris.add("your_new_uri_here"); MyContentProvider.addNewUris(newUris);遵循ContentProvider设计规范,用ContentResolver间接操作
如果需求是修改Provider对外提供的数据,更合规的方式是在MyContentProvider中实现insert/update方法,然后通过ContentResolver调用:// MyContentProvider中实现insert方法 @Override public Uri insert(Uri uri, ContentValues values) { String newUri = values.getAsString("uri"); sUris.add(newUri); return uri; } // MainActivity中调用 ContentResolver resolver = getContentResolver(); Uri providerUri = Uri.parse("content://com.i.sticker_admin.mycontentprovider/uris"); ContentValues values = new ContentValues(); values.put("uri", "your_new_uri"); resolver.insert(providerUri, values);跨进程场景注意事项
如果你的ContentProvider被多进程访问,静态变量无法跨进程共享,此时需要改用数据库、SharedPreferences或AIDL等跨进程通信机制来同步数据。
内容的提问来源于stack exchange,提问作者Étalo Garleni Rodríguez
相关产品推荐
相关产品推荐

