проблемы с настройкой базы данных db4o

Я пытаюсь использовать одноэлементный класс для создания этой базы данных, потому что мне нужно, чтобы она была открыта для каждого действия в приложении. Я продолжаю получать ошибку нулевого указателя из вызовов «getFilesDir» или «if (instance == null), и, поскольку я не так хорошо знаком с программированием для Android, я не уверен, что происходит.

package com.database;

import java.io.File;

import android.app.Application;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.util.Log;

import com.businessclasses.Field;
import com.db4o.Db4oEmbedded;
import com.db4o.ObjectContainer;
import com.db4o.config.AndroidSupport;
import com.db4o.config.EmbeddedConfiguration;

public final class anotherTest extends Application {
    private static ObjectContainer playsDB;
    private static ObjectContainer gamePlanDB;

    private anotherTest instance;

    public anotherTest(){

        final EmbeddedConfiguration config = Db4oEmbedded.newConfiguration();
        config.common().add(new AndroidSupport());
        //instance.getFilesDir().getPath()
        new File(getFilesDir().getPath(), "/PlaysDB.db4o").delete();

        Log.d("db", "" + instance.getFilesDir().getPath());
        //getFilesDir().getPath();
        //String appPath = "/data/data/PlaysDB/database";

        playsDB = Db4oEmbedded.openFile(config, getFilesDir().getPath() +     "/PlaysDB.db4o");
        //File test = new File(appPath + "/PlaysDB.db4o");
        //if(test != null){
        //  Log.d("db", "file was created");
        //  Log.d("db", "path >> " + test.getAbsolutePath());
            //test.delete();
        //}

        //playsDB = Db4oEmbedded.openFile(config, appPath + "/PlaysDB.db4o");
    }

    public synchronized anotherTest getInstance(){
        if(instance == null){
            instance = new anotherTest();
        }
        return instance;
    }

    public void storePlay(Field field){
        if(field != null){
            if(playsDB == null){
                Log.d("db", "database is null");
            }
            playsDB.store(field);
            playsDB.commit();
            Log.d("added play", "play added to db");    
        }
        else{
            Log.e("field input null", "play not added to db");
        }
    }   
}

И вот мой звонок в одном из мероприятий.

   public void onClick(View v) {
        String formation = playFormation.getText().toString();
        String name = playName.getText().toString();
        String type = playType.getSelectedItem().toString();
        //TODO:send to database

        Field newField = new Field();
        newField.setPlayName(name);
        newField.setPlayType(type);

        anotherTest temp = new anotherTest();
        temp.getInstance().storePlay(newField);
    }

Последние несколько недель пытались заставить эту базу данных работать, но безрезультатно. Любая помощь или руководство будет принята с благодарностью.


person user1799107    schedule 08.11.2012    source источник


Ответы (1)


То, как это структурировано, не имеет смысла.

  • Классы Java всегда называются в правильном регистре, поэтому это должно быть "AnotherTest".
  • На самом деле вы не создаете синглтон, потому что ни ваш экземпляр, ни ваш getInstance() не являются статическими. Кроме того, вы никогда не получаете доступ к своему экземпляру через «getInstance()».
  • У вас есть класс AnotherTest, полем которого является экземпляр AnotherTest, который никогда не инициализируется и доступ к которому осуществляется в конструкторе AnotherTest. Это просто гарантированно будет нулевым.
  • Вы полагаетесь на неявное состояние суперкласса Application, которое никогда не предоставляется, потому что Application должен быть объявлен в файле androidmanifest.xml, где он будет создан для вас. Между тем, вы создаете экземпляр вручную в своем обработчике событий, поэтому он не имеет ожидаемого состояния, но в любом случае он упадет в своем собственном конструкторе, потому что он пытается сослаться на нулевой указатель на себя, как упоминалось выше.

Ваши проблемы не связаны с DB40, а связаны с непониманием того, что вы делаете.

Это должно быть больше похоже на:

public final class AnotherTest {


    private static AnotherTest instance;

    private final Context context;

    private AnotherTest(Context context){
        this.context = context;

        // Do whatever you need to do with DB4O using *only* the supplied context here
    }

    public static synchronized AnotherTest getInstance(Context context){
        if(instance == null){
            instance = new AnotherTest(context);
        }
        return instance;
    }
}

И в обработчике событий:

AnotherTest.getInstance(Context.getApplicationContext()).storePlay(newField);
person Dave    schedule 08.11.2012
comment
Единственная проблема с использованием этого вызова в четном обработчике заключается в том, что мы получаем статическую ссылку на ошибку нестатического метода при использовании getApplicationContext() из действий. - person user1799107; 09.11.2012
comment
Был в состоянии использовать AnotherTest.getInstance(getBaseContext()).storePlay(newField); И на данный момент он работает после нескольких небольших быстрых тестов, которые я провел. Еще раз большое спасибо за помощь и объяснение того, что пошло не так, я очень ценю это! - person user1799107; 09.11.2012