super.getWritableDatabase () аварийно завершает работу при вызове из MyApplication, которая находится в проекте библиотеки - PullRequest
1 голос
/ 04 ноября 2011

У меня есть несколько приложений, которые спроектированы одинаково.Расширенное приложение содержит соединение с базой данных, а расширенное SQLiteOpenHelper содержит весь код.

Это работает при использовании в стандартном проекте Android.

Сбой, когда расширенное приложение находится в библиотечном проекте.

Следующий код является расширенным классом Application.Он находится в проекте библиотеки.Сбой происходит, если он используется в проекте библиотеки, но не в том случае, если он является частью стандартного приложения Android без проекта библиотеки.Я попытался переместить класс MyApplication из Библиотечного проекта в проект (изменив имя в манифесте) - безуспешно.

Полагаю, но я просто ловлю рыбу здесь, так как MySQLiteOpenHelper использует права /разрешения / местоположение проекта библиотеки, а не самого проекта.

public class MyApplication extends Application {

    private static SQLiteDatabase     sqliteDatabase;
    private static MySQLiteOpenHelper sqliteOpenHelper;

    public static SQLiteDatabase getSqliteDatabase() {
        return sqliteDatabase;
    }

    public static MySQLiteOpenHelper getSqliteOpenHelper() {
        return sqliteOpenHelper;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        MyPreferenceActivity.createSettings(getApplicationContext());

        sqliteOpenHelper = new MySQLiteOpenHelper(getApplicationContext());
        if (sqliteOpenHelper != null) {
            sqliteDatabase = sqliteOpenHelper.getWritableDatabase();
        }
    }
}

Это часть расширенного класса SQLiteOpenHelper:

public class MySQLiteOpenHelper extends SQLiteOpenHelper {

    private static final int      DATABASEVERSION = 18;
    private static final String   DATABASENAME = "myproduct.db";

    private Context               context;
    private SQLiteDatabase        sqliteDatabase;
    private String                location; 

    public MySQLiteOpenHelper(final Context context) {
        super(context, DATABASENAME, null, DATABASEVERSION);

        this.context = context;
    }

    @Override
    public SQLiteDatabase getWritableDatabase() {
            ...
    try {
        if (Tools.isSDCardWriteable() && (fileSdDbDir.exists() || fileSdDb.exists())) {
            // Database on SD-card works perfect
            // If I use this to create the internal database it fails here too
            location = sdDb;
            sqliteDatabase = SQLiteDatabase.openOrCreateDatabase(location, null);

            int version = sqliteDatabase.getVersion();

            if (version != DATABASEVERSION) {
                sqliteDatabase.beginTransaction();

                try {
                    if (version == 0) {
                        onCreate(sqliteDatabase);
                    } else {
                        onUpgrade(sqliteDatabase, version, DATABASEVERSION);
                    }

                    sqliteDatabase.setVersion(DATABASEVERSION);
                    sqliteDatabase.setTransactionSuccessful();
                } finally {
                    sqliteDatabase.endTransaction();
                }
            }

            onOpen(sqliteDatabase);
        } else {
            // internal database fails to create
            location = intDb;
            sqliteDatabase = super.getWritableDatabase(); <-- fails
        }
    } catch (Exception exception) {
    if (MyPreferenceActivity.DEBUG) Log.d("Exception", exception.getMessage()); <-- crashes
    }

    return sqliteDatabase;
    }

    @Override
    public void onCreate(final SQLiteDatabase sqliteDatabase) {
        //
    }

    @Override
    public void onUpgrade(final SQLiteDatabase sqliteDatabase, final int oldVersion, final int newVersion) {
        //
    }

    ...
}

Это манифест проекта библиотеки:

<?xml version="1.0" encoding="utf-8"?>

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="xxx.yyy.zzzlib.android" >

    <uses-sdk
        android:minSdkVersion="7"
        android:targetSdkVersion="11" />
</manifest>

Это часть манифеста проектов:

<?xml version="1.0" encoding="utf-8"?>

    <manifest
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:installLocation="preferExternal" 
        android:versionCode="41"
        android:versionName="5.0.3"
        package="xxx.yyy.zzz.android" >

        <application
            ...
            android:name="xxx.yyy.zzzlib.android.MyApplication" >
            ...
        </application>

        ...

        <uses-sdk
            android:minSdkVersion="7"
            android:targetSdkVersion="11" />
    </manifest> 

Понятия не имею, почему это не работает.Возможно, дело в контексте, но ошибка указывает на файл.У меня нет никаких подсказок.

Что-то не так с этим подходом?Он отлично работает в стандартной среде проекта Android.

Большое спасибо заранее.

РЕДАКТИРОВАТЬ:

Stacktrace показывает сбой в Log.d, но этосбой вызова базы данных:

11-04 17:53:56.143: E/AndroidRuntime(1127): FATAL EXCEPTION: main
11-04 17:53:56.143: E/AndroidRuntime(1127): java.lang.RuntimeException: Unable to create application xxx.yyy.zzzlib.android.MyApplication: java.lang.NullPointerException: println needs a message
11-04 17:53:56.143: E/AndroidRuntime(1127):     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3275)
11-04 17:53:56.143: E/AndroidRuntime(1127):     at android.app.ActivityThread.access$2200(ActivityThread.java:117)
11-04 17:53:56.143: E/AndroidRuntime(1127):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:969)
11-04 17:53:56.143: E/AndroidRuntime(1127):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-04 17:53:56.143: E/AndroidRuntime(1127):     at android.os.Looper.loop(Looper.java:130)
11-04 17:53:56.143: E/AndroidRuntime(1127):     at android.app.ActivityThread.main(ActivityThread.java:3683)
11-04 17:53:56.143: E/AndroidRuntime(1127):     at java.lang.reflect.Method.invokeNative(Native Method)
11-04 17:53:56.143: E/AndroidRuntime(1127):     at java.lang.reflect.Method.invoke(Method.java:507)
11-04 17:53:56.143: E/AndroidRuntime(1127):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
11-04 17:53:56.143: E/AndroidRuntime(1127):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
11-04 17:53:56.143: E/AndroidRuntime(1127):     at dalvik.system.NativeStart.main(Native Method)
11-04 17:53:56.143: E/AndroidRuntime(1127): Caused by: java.lang.NullPointerException: println needs a message
11-04 17:53:56.143: E/AndroidRuntime(1127):     at android.util.Log.println_native(Native Method)
11-04 17:53:56.143: E/AndroidRuntime(1127):     at android.util.Log.d(Log.java:137)
11-04 17:53:56.143: E/AndroidRuntime(1127):     at xxx.yyy.zzzlib.android.MySQLiteOpenHelper.getWritableDatabase(MySQLiteOpenHelper.java:1493)
11-04 17:53:56.143: E/AndroidRuntime(1127):     at xxx.yyy.zzzlib.android.MyApplication.onCreate(MyApplication.java:27)
11-04 17:53:56.143: E/AndroidRuntime(1127):     at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:969)
11-04 17:53:56.143: E/AndroidRuntime(1127):     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3272)

1 Ответ

0 голосов
/ 04 ноября 2011

1) Опубликовать больше трассировки стека. Очень мало контекста. 2) 'if (sqliteOpenHelper! = Null) {' не требуется. Это никогда не будет нулевым. 3) Переопределение getWritableDatabase не имеет никакого смысла, по крайней мере, в этом контексте. Я бы не стал этого делать. 4) OnCreate вашего вспомогательного класса пуст. Я предполагаю, что вы сделали это перед публичной публикацией?

Если ваш вспомогательный класс попытается открыть базу данных по пути, указанному в пакете LIBRARY, я мог бы понять, как это может быть проблемой. Не уверен, как разрешения для файлов работают с проектами библиотеки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...