未在模拟器上调用 Android Room OnCreate 回调

Android Room OnCreate Callback isn't being called on emulator

提问人:Jordan Case 提问时间:7/11/2019 最后编辑:Amaresh S MJordan Case 更新时间:7/12/2019 访问量:207

问:

我正在尝试初始化我的 android 房间数据库。我尝试在 asyncTask 中调用 userDAO 以启动首次运行的 onCreate 回调。onCreate 回调将预填充我的数据库。它返回一个 null 指针。 我不确定它是否与asyncTask调用另一个asynctask有关,并且在数据库预填充之前完成,或者我是否错误地使用了回调。提前感谢您的任何反馈!

这是数据库文件

    @Database(entities = {UserDB.class}, version = 1, exportSchema = false)
    public abstract class RoomDatabase extends androidx.room.RoomDatabase {

    //create the name for the database and create an empty instance
    private static final String DB_NAME = "person_DB";
    private static RoomDatabase instance;
    //create connection to the DAO for personal database
    public abstract UserDAO userDAO();
    public static RoomDatabase getInstance(Context context) {
        return instance;
    }
    //when called, check for instance of database, but if not there, create an instance with context, database, and name of db
    public static RoomDatabase getDbInstance(Context context) {
        if(instance == null) {
            synchronized (RoomDatabase.class) {
                if (instance == null) {
                    instance = Room.databaseBuilder(context.getApplicationContext(), RoomDatabase.class, DB_NAME)
                            .addCallback(rdc)
                            .build();
                }
            }
        }
        System.out.println("returning instance of db");
        return instance;
    }

    //Create a callback to populate the database with the users profile information
    private static RoomDatabase.Callback rdc = new RoomDatabase.Callback() {
        //make method for creating first database outline
        @Override
        public void onCreate (SupportSQLiteDatabase db) {
            super.onCreate(db);
            System.out.println("entering onCreate");
            new PopulateDbAsyncCreate(instance).execute();
        }
       public void onOpen (SupportSQLiteDatabase db) {
           //empty for now
       }
    };

    }

this is the pre populate file

    class PopulateDbAsyncCreate extends AsyncTask <Void,Void,Void> {
    //member variable for getting user dao
    private final UserDAO mUserDAO;

    //get the DAO on construction to edit db with
    public PopulateDbAsyncCreate(RoomDatabase mdb) {
        mUserDAO = mdb.userDAO();
    }
    //in background remove all data inside user-profile and replace with empty inserted
     @Override
    protected Void doInBackground(final Void... params) {
        if(mUserDAO.getAnyUser().getFirstName().isEmpty()) {
            mUserDAO.deleteAll();
            UserDB user = new UserDB("new", null, null, 0, 0,
                    0, 0, 0);
            mUserDAO.insert(user);
        }
        return null;
    }
}

最后,这是我的主要功能

   public class MainActivity extends AppCompatActivity {
    public RoomDatabase mdb;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //create instance of DB IDK if I need to change this to getting an instance of DB
        mdb = RoomDatabase.getDbInstance(this);
        //check database to see if it is empty using asyncTASK
        CheckDB check = new CheckDB(mdb);
        check.execute();

        //set button listener to go to home page
        final Button button;
        button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            goToCreateUser();
            }
        });
    }

    //method for going to createUser Screen
    private void goToCreateUser() {
        startActivity(new Intent(MainActivity.this, CreateUser.class));
        this.finish();
    }

    //method for going to home screen after button press and finishing this current activity
    private void goToHomeScreen() {
        startActivity(new Intent(this, home.class));
        this.finish();
    }


    //inner class for checking if database exists
    public class CheckDB extends AsyncTask<Void,Void,String> {
        //init member of db
        private RoomDatabase mdb;

        //constructor for setting db member to current db of app
        public CheckDB(RoomDatabase mdb) {
            this.mdb = mdb;
        }

        //on execute it checks to see if any user exists and returns null if they do exist
        @Override
        protected String doInBackground(Void... voids) {
            UserDAO userDAO = mdb.userDAO();
            final String name = userDAO.getAnyUser().getFirstName();
            if(name.equals("new") || name.isEmpty()) {
                return null;
            }
            return "GoodTOGO";
        }

        //receives output of doInBackground and performs screen change if the user's profile already
        //exists
        @Override
        protected void onPostExecute(String input) {
            String s = input;
            if(s != null) {
                goToHomeScreen();
            }
        }
    }
}
java android nullpointerexception android-asynctask android-room

评论

0赞 KuLdip PaTel 7/11/2019
从代码“public static RoomDatabase getInstance(Context context) { return instance; }”中删除此行。
0赞 Jordan Case 7/12/2019
我试过了这个,它不能解决我遇到的错误。我仍然收到空指针。我想那行是多余的,对吧?
0赞 Mahdi 3/8/2022
对我来说,这是没有表和没有版本的调用!

答: 暂无答案