一、日志:
crash
2024-10-25 12:15:33.020 ?2113-2113 ?AndroidRuntime ? ? ? ? ?pid-2113 ? ? ? ? ? ? ? ? ? ? ? ? ? ? E ?FATAL EXCEPTION: main
Process: com..workhome, PID: 2113
java.lang.RuntimeException: Unable to start activity ComponentInfo{com..workhome/com.workhome.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'androidx.lifecycle.LiveData com.kingtop.workhome.room.AppRepository.getAllApps()' on a null object reference
?? ?at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3484)
?? ?at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3648)
?? ?at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
?? ?at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
?? ?at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
?? ?at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2116)
?? ?at android.os.Handler.dispatchMessage(Handler.java:106)
?? ?at android.os.Looper.loop(Looper.java:223)
?? ?at android.app.ActivityThread.main(ActivityThread.java:7723)
?? ?at java.lang.reflect.Method.invoke(Native Method)
?? ?at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:612)
?? ?at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:997)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'androidx.lifecycle.LiveData com.workhome.room.AppRepository.getAllApps()' on a null object reference
?? ?at com.workhome.MainActivity.setData(MainActivity.java:528)
?? ?at com.workhome.MainActivity.onCreate(MainActivity.java:457)
?? ?at android.app.Activity.performCreate(Activity.java:8000)
?? ?at android.app.Activity.performCreate(Activity.java:7984) ? ?
中文回復,難道mAppRepository 這個為空?
是因為private void initRoom() {
? ? ? ? Log.d(TAG, "initRoom: Starting");
? ? ? ? new Thread(() -> {
? ? ? ? ? ? AppDatabase db = AppDatabase.getInstance(this);
? ? ? ? ? ? AppInfoDao dao = db.appInfoDao();
? ? ? ? ? ? mAppRepository = new AppRepository(dao);
? ? ? ? ? ? runOnUiThread(() -> Log.d(TAG, "initRoom: Room database initialized"));
? ? ? ? }).start();
? ? ? ? Log.d(TAG, "initRoom: Thread started");
? ? }
二、提問:開了一個線程在初始化,就是還沒初始化完成,就立馬調用mAppRepository導致?
三、解決辦法:可以把 setData() 的調用移動到初始化完成的回調中(UI線程)
?? ? private void initRoom() {
? ? ? ? Log.d(TAG, "initRoom: Starting");
? ? ? ? new Thread(() -> {
? ? ? ? ? ? AppDatabase db = AppDatabase.getInstance(this);
? ? ? ? ? ? AppInfoDao dao = db.appInfoDao();
? ? ? ? ? ? mAppRepository = new AppRepository(dao);
// ? ? ? ? ? ?runOnUiThread(() -> Log.d(TAG, "initRoom: Room database initialized"));
? ? ? ? ? ? runOnUiThread(() -> {
? ? ? ? ? ? ? ? Log.d(TAG, "initRoom: Room database initialized");
? ? ? ? ? ? ? ? setData(); // ← 初始化完成后再調用
? ? ? ? ? ? });
? ? ? ? }).start();
? ? ? ? Log.d(TAG, "initRoom: Thread started");
? ? }
?