英文:
Null pointer exception on Room Database; on getDatabase() method
问题
我需要使用Room数据库在片段中进行“待办事项列表”。我在Android上是一个非常初学者。这是我遇到的问题:
进程:com.example.todolistwithroom,PID:29204
java.lang.NullPointerException:尝试调用虚拟方法'com.example.todolistwithroom.AppDatabase com.example.todolistwithroom.App.getDatabase()'时出现空对象引用
at com.example.todolistwithroom.Todo.onViewCreated(Todo.java:32)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1471)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3273)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:620)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1392)
at android.app.Activity.performStart(Activity.java:7252)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2970)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6810)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
这是我的片段:
public class Todo extends Fragment{
AppDatabase appDatabase;
RecyclerView recyclerView;
RecyclerView.Adapter adapter;
Button button;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_main,container,false);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
appDatabase = App.getInstance().getDatabase();
TodoTaskDao taskDao = appDatabase.todoTaskDao();
recyclerView = view.findViewById(R.id.rv_todo_main);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
adapter = new TodoAdapter(taskDao.getAll());
recyclerView.setAdapter(adapter);
button = view.findViewById(R.id.B_add_task_button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getContext(),AddMainActivity.class);
startActivity(intent);
getActivity().finish();
}
});
}
}
App类初始化的位置:
public class App extends Application {
public static App instance;
private AppDatabase database;
@Override
public void onCreate() {
super.onCreate();
instance = this;
database = Room.databaseBuilder(this, AppDatabase.class, "database")
.allowMainThreadQueries()
.build();
}
public static App getInstance() {
return instance;
}
public AppDatabase getDatabase() {
return database;
}
}
自己的数据库类:
package com.example.todolistwithroom;
import androidx.room.Database;
import androidx.room.RoomDatabase;
@Database(entities = {TodoTask.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract TodoTaskDao todoTaskDao();
}
清单文件:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:name=".App">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
英文:
I need to use Room database to do "Todo list" using fragments. I am very beginner on android. This is problem i have got
java.lang.NullPointerException: Attempt to invoke virtual method 'com.example.todolistwithroom.AppDatabase com.example.todolistwithroom.App.getDatabase()' on a null object reference
at com.example.todolistwithroom.Todo.onViewCreated(Todo.java:32)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1471)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3273)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:620)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1392)
at android.app.Activity.performStart(Activity.java:7252)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2970)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6810)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
This is my fragment
public class Todo extends Fragment{
AppDatabase appDatabase;
RecyclerView recyclerView;
RecyclerView.Adapter adapter;
Button button;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_main,container,false);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
appDatabase = App.getInstance().getDatabase();
TodoTaskDao taskDao = appDatabase.todoTaskDao();
recyclerView = view.findViewById(R.id.rv_todo_main);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
adapter = new TodoAdapter(taskDao.getAll());
recyclerView.setAdapter(adapter);
button = view.findViewById(R.id.B_add_task_button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getContext(),AddMainActivity.class);
startActivity(intent);
getActivity().finish();
}
});
}
}
App class where it initialized
public class App extends Application {
public static App instance;
private AppDatabase database;
@Override
public void onCreate() {
super.onCreate();
instance = this;
database = Room.databaseBuilder(this, AppDatabase.class, "database")
.allowMainThreadQueries()
.build();
}
public static App getInstance() {
return instance;
}
public AppDatabase getDatabase() {
return database;
}
}
and self database class
package com.example.todolistwithroom;
import androidx.room.Database;
import androidx.room.RoomDatabase;
@Database(entities = {TodoTask.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract TodoTaskDao todoTaskDao();
}
Manifest:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:name=".App">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
If anything else neeeded to specify, it will be added. I have no clue what is going on, because my friends have the same database code.
专注分享java语言的经验与见解,让所有开发者获益!
评论