Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sporadic IllegalArgumentException: Unknown URL content://

Very rarely getting:

Fatal Exception: java.lang.IllegalArgumentException: Unknown URL content://com.example.provider/info  
    at android.content.ContentResolver.insert(ContentResolver.java:1252)

Fatal Exception: java.lang.IllegalArgumentException: Unknown authority com.example.provider
    at android.content.ContentResolver.applyBatch(ContentResolver.java:1247)

Emphasis on rarely. Generally work fine without issue, so the authorities is set up fine, but this is showing up every once in a while for no reason. Are there reasons why the ContentResolver may not be able to find a ContentProvider (i.e. if not set up yet)?

like image 577
David Liu Avatar asked Jan 04 '17 22:01

David Liu


1 Answers

I've had the rare IllegalArgumentException with Unknown URIs issue when I was doing ContentResolver operations in the custom Application object.

For example, I was trying to delete items in my content provider in the application onCreate method which would very occasionally crash:

public class CustomApplication extends Application {

    @Override
    public void onCreate() {
        //..
        context.getContentResolver().delete(ReminderEntry.getContentURI(), null, null, null, null);
        //.. 
    }
}

Which would sometimes render the following crash:

Fatal Exception: java.lang.RuntimeException: Unable to create application com.myapp.CustomApplication: java.lang.IllegalArgumentException: Unknown URL content://com.myapp.db.CustomContentProvider/reminder
   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://com.myapp.db.CustomContentProvider/reminder
       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)

I also saw similar behaviour with a BOOT_COMPLETE receiver. I had about 70 reported crashes with this exception (mostly Infinix devices ~43%, hardly any Samsung Devices) of about 200 000 monthly active users. IllegalArguementException Device Stats

I moved this into a background scheduled job and haven't seen the crash since. I was only ever able to reproduce this issue once on a Nexus device that I used but never again.

I suspect perhaps sometimes on some versions of Android on some devices the Application/BOOT_COMPLETE Receiver initializes before the ContentProvider is fully initialized and therefore when it tries to access it, it is not properly set up yet.

There are a couple of stackoverflow posts that do state exactly what is created first and how the OS should behave:

Is the Application class guaranteed to be instantiated before a defined boot receiver is called

But like I said, I've seen otherwise and moving operations out of the classes into background schedulers seems to fix the problem (perhaps it is just because it takes a bit longer to get setup). Hopefully my experience will help you.

Edit: I used the evernote job dispatcher and deferred my ContentResolver operations to the job if required. (but I would assume that deferring the content provider operation to any kind of background processing might fix it as it had a bit more time to get setup - these are just my suspicions of course).

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;
    }
}
like image 140
riggaroo Avatar answered Nov 03 '22 22:11

riggaroo