Search code examples
androidandroid-contentprovidercrud

AsyncQueryHandler with ContentProvider is necessary?


my question is very simple: if I insert or update or delete a single row in a SQLLite database through a ContentProvider from a UIThread, is the AsyncQueryHandler's implementation necessary?

I know that the best practice is to implement the CRUD operations in a async task but also that the CRUD stantment about one row is not so heavy to perform. Infact also Android Studio does not alert his stantment that shouldn't run on UI Thread and all the guides that I found on the net about the ContentProvider don't mention the ASyncQueryHandler. All the CRUD operations are performed on the UI Thread invoked directly the ContentProvider.


Solution

  • It's probably best to just go the Async route for all your ContentProvider operations. I know it can be a pain but consider this:

    Your simple, one-row insert that usually takes a few milliseconds having to wait for a larger transaction to complete. Maybe you're busy in a SyncAdapter doing lots of stuff? Your little tiny insert suddenly takes much longer and might even cause an ANR.

    I know it's a pretty low chance, but the chance is still there. Much better to just accept the boilerplate code and get on with it ;-)

    Example boilerplate code to paste into an activity class:

    private class UpdateHandler extends AsyncQueryHandler {
    
        private final WeakReference<YourActivityClass> mActivityRef;
    
        public UpdateHandler(YourActivityClass activity, ContentResolver cr) {
            super(cr);
    
            mActivityRef = new WeakReference<>(activity); // do a weak reference incase the update takes ages and the activity gets destroyed during
        }
    
        @Override
        protected void onUpdateComplete(int token, Object cookie, int result) {
            super.onUpdateComplete(token, cookie, result);
    
            YourActivityClass exampleActivity = mActivityRef.get();
            if (exampleActivity != null) {
                exampleActivity .onUpdateCompleted(token);
            }
        }
    }
    
    
    public void saveStuffToDatabase() {
    
        // do some stuff like show a progress bar or whatever
    
        // actually do the update operation
        new UpdateHandler(this, getContentResolver()).startUpdate(
                0,              // this will be passed to "onUpdatedComplete" in the updateHandler
                null,           // so will this!
                uri,
                values
        );
    
    
    }
    
    private void onUpdateCompleted(int token) {
        // this runs in the main thread after the update you started in saveStuffToDatabase() is complete
    
    }