Inject database in a ContentProvider with dagger

前端 未结 5 2431
无人及你
无人及你 2021-02-19 22:57

I want to inject a singleton SqliteOpenHelper in a ContentProvider. However, it seems that the ContentProvider instance is being built bef

5条回答
  •  傲寒
    傲寒 (楼主)
    2021-02-19 23:16

    As Alex Baker pointed out, the solution of the issue is to defer the injection when an operation (query, insert, update, delete) is called for the first time.

    to make an example:

    This won't work:

    public class YourProviderNull extends ContentProvider {
    
    
    @Inject
    YourSQLHelper yourHelper;
    
    
    @Override
    public boolean onCreate() {
        YourActivity.getComponent().inject(this); //NPE!!!
        //other logic
        return true;
    }
    
    @Override
    public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs,
                        String sortOrder) {
        SQLiteDatabase db = yourHelper.getReadableDatabase();
        //other logic
    }
    
    
    @Override
    public Uri insert(@NonNull Uri uri, ContentValues values) {
        SQLiteDatabase db = yourHelper.getWritableDatabase();
        //other logic
    }
    
    @Override
    public int delete(@NonNull Uri uri, String selection, String[] selectionArgs) {
        SQLiteDatabase db = yourHelper.getWritableDatabase();
        //other logic
    }
    
    @Override
    public int update(@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        SQLiteDatabase db = yourHelper.getWritableDatabase();
        //other logicreturn db.update(resolveTableNameForUri(uri), values, selection, selectionArgs);
    }
    

    }

    but this will work correctly:

    public class YourProviderWorking extends ContentProvider {
    
    
    @Inject
    YourSQLHelper yourHelper;
    
    
    @Override
    public boolean onCreate() {
    
        //other logic
        return true;
    }
    
    @Override
    public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs,
                        String sortOrder) {
        if(yourHelper == null){
            deferInit();
        }
        SQLiteDatabase db = yourHelper.getReadableDatabase();
        //other logic
    }
    
    
    @Override
    public Uri insert(@NonNull Uri uri, ContentValues values) {
        if(yourHelper == null){
            deferInit();
        }
        SQLiteDatabase db = yourHelper.getWritableDatabase();
        //other logic
    }
    
    @Override
    public int delete(@NonNull Uri uri, String selection, String[] selectionArgs) {
        if(yourHelper == null){
            deferInit();
        }
        SQLiteDatabase db = yourHelper.getWritableDatabase();
        //other logic
    }
    
    @Override
    public int update(@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        if(yourHelper == null){
            deferInit();
        }
        SQLiteDatabase db = yourHelper.getWritableDatabase();
        //other logicreturn db.update(resolveTableNameForUri(uri), values, selection, selectionArgs);
    }
    
    private void deferInit(){
        YourActivity.getComponent().inject(this);
    }
    

    }

提交回复
热议问题