我想注入一个单身SqliteOpenHelper的ContentProvider.但是,似乎ContentProvider在创建Application实例之前构建实例(getApplicationContext()返回null).我什么时候可以注入数据库?我已经尝试过构造函数和onCreate()方法ContentProvider.
这有一个简单的原因,
onCreate()在Application中的相应方法之前调用提供程序.例如,您可以在Application的另一个方法中创建组件attachBaseContext.
1将您的逻辑从应用程序中onCreate移到attachBaseContext.
@Override
public void attachBaseContext(Context base){
super.attachBaseContext(base);
mApplicationComponent = DaggerApplicationComponent.builder()
.applicationModule(new ApplicationModule(this))
.build();
mApplicationComponent.inject(this);
}
Run Code Online (Sandbox Code Playgroud)
2现在,您可以inject在OnCreate您的ContentProvider:
public boolean onCreate() {
YourMainApplication.get(getContext()).getComponent().inject(this);
return true;
}
Run Code Online (Sandbox Code Playgroud)
免责声明:来自俄罗斯博客 @LeEnot的完全信誉:内容提供商中的Dagger2 Inject.为方便起见,此处列出了答案,因为它没有英文版本.
我遇到了同样的问题,不得不推迟注射,直到需要数据库.您可以使用Dagger的懒惰注射来达到相同的效果.
来自内容提供商的onCreate文档:
您应该推迟非常重要的初始化(例如打开,升级和扫描数据库),直到使用内容提供程序
显然这个建议不能被忽视.实现onCreate()方法提供了一个使用SQLiteOpenHelper和内容提供程序的示例.
正如Alex Baker指出的那样,问题的解决方案是在第一次调用操作(查询,插入,更新,删除)时推迟注入.
举个例子:
这不起作用:
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);
}
Run Code Online (Sandbox Code Playgroud)
}
但这将正常工作:
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);
}
Run Code Online (Sandbox Code Playgroud)
}