我曾在自定义的Application对象中进行ContentResolver操作时,遇到了罕见的IllegalArgumentException和未知URI问题。
例如,在应用程序的onCreate方法中尝试删除内容提供程序中的项目,但偶尔会崩溃。
public class CustomApplication extends Application {
@Override
public void onCreate() {
context.getContentResolver().delete(ReminderEntry.getContentURI(), null, null, null, null);
}
}
有时会导致以下崩溃:
Fatal Exception: java.lang.RuntimeException: Unable to create application com.myapp.CustomApplication: java.lang.IllegalArgumentException: Unknown URL content:
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6431)
at android.app.ActivityThread.access$1800(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1887)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7331)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by java.lang.IllegalArgumentException: Unknown URL content:
at android.content.ContentResolver.delete(ContentResolver.java:1376)
at com.myapp.ReminderEntryDao.delete(Unknown Source)
at com.myapp.CustomApplication.onCreate(Unknown Source)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1037)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6428)
at android.app.ActivityThread.access$1800(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1887)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7331)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
我还看到了类似的行为,使用
BOOT_COMPLETE
接收器。每月活跃用户约20万人中,我有大约70个报告的崩溃异常(大多是Infinix设备约43%,几乎没有三星设备)。
我将其移入后台计划任务,自那以后就没有再出现过崩溃。我只能在我用过但从未再次遇到的Nexus设备上重现此问题。
我怀疑在某些Android版本的某些设备上,
Application
/
BOOT_COMPLETE
接收器在
ContentProvider
完全初始化之前进行了初始化,因此当它尝试访问时,它尚未正确设置。
有一些stackoverflow帖子确实说明了首先创建什么以及操作系统应该如何行动:
Is the Application class guaranteed to be instantiated before a defined boot receiver is called
但是,正如我所说的,我也看到了不同的情况,将操作从类中移动到后台调度程序似乎可以解决问题(也许只是因为设置需要更长时间)。希望我的经验能对您有所帮助。
编辑:我使用了 evernote工作调度器,如果需要,将我的ContentResolver
操作推迟到了工作中。(但我认为将内容提供程序操作推迟到任何一种后台处理可能会修复它,因为它有更多的时间来设置 - 当然这只是我的猜测)。
class DeleteRemindersJob extends Job {
@NonNull
@Override
protected Result onRunJob(final Params params) {
cursor = getContext().getContentResolver().delete(ReminderEntry.getContentURI(), null, null, null, null);
return Result.SUCCESS;
}
}