android - 从 IntentService 构造函数打开数据库连接

标签 android sqlite service

当尝试通过正常机制打开数据库连接时,在点 dbhelper.getWritableDatabase 处抛出一个 nullpointerexecption

问题似乎源于我传入的 IntentService 上下文。

    public AnalysisService() {
    super("AnalysisService");
    Log.d("ANALYSIS_SERVICE", "Service started");
    try{
    db = new DBAdapter(this)
    db.openDB();
    }catch(Exception e){
        Log.d("ANALYSIS_SERVICE", Arrays.toString(e.getStackTrace()));
        Log.e("ANALYSIS_SERVICE", e.toString());
    }
}

db.open方法在这里执行:

public class DBAdapter implements Database {

protected Context context;
protected SQLiteDatabase db;
private DatabaseHelper dbHelper;

public DBAdapter(Context context) {
    this.context = context;
    Log.e("DB_ADAPTER", "CREATED");
}

/**
 * Opens a database connection.
 * @return
 * @throws SQLException
 */
@Override
public DBAdapter openDB() throws SQLException {
    dbHelper = new DatabaseHelper(context);
    db = dbHelper.getWritableDatabase(); //NULLP EXCEPTION THROWN HERE
    return this;
}

如果它有助于 dbHelper 的构造函数是:

    public DatabaseHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
    Log.e("DB_HELPER", "created");
}

这让我困惑了大约一天,所以我不明白为什么上下文无效。此外,我已经记录了所有构造函数并且所有对象都被正确创建,所以 DBHelper 不是空的。

除了像这样使用上下文外,我还尝试使用 getBaseContext()getApplicationContext(),两者都导致相同的错误。

从打印堆栈跟踪的调试中,我得到:

    11-21 13:23:45.419: D/ANALYSIS_SERVICE(3930): 
[android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221), 
android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:166), 
com.emotifi.database.DBAdapter.openDB(DBAdapter.java:42), 
com.emotifi.analysis.AnalysisService.<init>(AnalysisService.java:45),
 java.lang.Class.newInstanceImpl(Native Method), 
java.lang.Class.newInstance(Class.java:1319), 
android.app.ActivityThread.handleCreateService(ActivityThread.java:2234), 
android.app.ActivityThread.access$1600(ActivityThread.java:123), 
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1201), 
android.os.Handler.dispatchMessage(Handler.java:99), 
android.os.Looper.loop(Looper.java:137), 
android.app.ActivityThread.main(ActivityThread.java:4424), 
java.lang.reflect.Method.invokeNative(Native Method), 
java.lang.reflect.Method.invoke(Method.java:511), 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:817), 
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584), 
dalvik.system.NativeStart.main(Native Method)]

最佳答案

您在 IntentService 生命周期中过早地设置上下文。

覆盖 onCreate 并将其设置在那里:

@Override
public void onCreate() {
    super.onCreate();
    Log.d("ANALYSIS_SERVICE", "Service started");
    db = DatabaseFactory.getDefault(this);
}

然后在onHandleIntent中打开数据库连接:

@Override
protected void onHandleIntent(Intent intent) {
    // Logging
    Log.d("ANALYSIS_SERVICE", "Intent handled");

    try {
        db.openDB();
    } catch (Exception e) {
        Log.d("ANALYSIS_SERVICE", "Unable to open database");
        e.printStackTrace();
    }
}

关于android - 从 IntentService 构造函数打开数据库连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13494419/

相关文章:

java - 从 asynctask 获取结果并处理它

java - Android SQLite 问题 - 表 __ 没有名为 ___ 的列

java - SQLite插入函数/方法参数参数太多,如何重构?

python - 对于一对多数据库模型,如何编写 sqlite 查询以避免 python 中的循环?

android - select 中的 Ormlite 子查询

android - AndEngine和engine.jar文件

android - 如果我选择大图像,OnActivityResult 会崩溃

android - Android 上 BOOT_COMPLETED 和 QUICKBOOT_POWERON 的区别

windows - 我们什么时候应该在 IIS 中托管 WCF 服务,什么时候应该在 Windows 服务中托管?

android - 在没有 Activity 的情况下在启动时启动服务