转到另一个 activity 时出现异常

Exception when going to another activity

我在转到另一个 activity 时一直收到 NullPointerException,而 app/emulator 就崩溃了。

清单文件包含这两个活动。

这里是 MainActivity:

public class MainActivity extends AppCompatActivity {
//Garbage Sorting V1

// GUI variables
private Button whereIsItems;
private Button addItem;
private TextView items;
private TextView listThings;


// Model: Database of items
private static ItemsDB itemsDB;

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

    itemsDB = new ItemsDB();
    itemsDB.fillItemsDB();

    items = findViewById(R.id.items);
    items.setText("Where to place them:");

    listThings = findViewById(R.id.edit_text);

    whereIsItems = findViewById(R.id.where_button);
    whereIsItems.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            items.setBackgroundColor(Color.parseColor("#FFFFFF"));
            String str = listThings.getText().toString();
            listThings.setText(itemsDB.getItemValue(str));
        }
    });

    addItem = findViewById(R.id.add_button1);
    assert addItem != null;
    addItem.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(MainActivity.this, GarbageActivity.class);
            startActivity(intent);
        }
    });
}

另一个 activity GarbageActivity(我想去的那个):

public class GarbageActivity extends AppCompatActivity {
private static ItemsDB itemsDB;
private EditText whatText;
private EditText whereText;
private Button addItem;

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

    itemsDB = ItemsDB.get(GarbageActivity.this);

    addItem = findViewById(R.id.add_button2);
    addItem.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            whatText = findViewById(R.id.what_text);
            whereText = findViewById(R.id.where_text);

            String str1 = whatText.getText().toString();
            String str2 = whereText.getText().toString();

            itemsDB.addItem(str1, str2);
            whatText.setText("");
            whereText.setText("");
        }
    });
}

这里是 ItemsDB,因为调试器说这里有错误:

public class ItemsDB {
private Map<String, Item> ItemsDB;
private static ItemsDB sItemsDB;

public ItemsDB() {
    ItemsDB = new HashMap<>();
}

private ItemsDB(Context context)  {
    fillItemsDB();
}

public static ItemsDB get(Context context) {
    if (sItemsDB == null) sItemsDB = new ItemsDB(context);
    return sItemsDB;
}

public void addItem(String what, String where) {
    Item it = new Item(what, where);
    ItemsDB.put(it.getWhat(), it);
}

public String getItemValue(String itemName) {
    Item item = ItemsDB.get(itemName);
    if (item == null) {
        return itemName + " not found";
    } else {
        return itemName + " should be placed in " + ItemsDB.get(itemName).getWhere();
    }
}

public void fillItemsDB() {
    addItem("Milk Carton", "Cardboard");
    addItem("Carrots", "Food");
    addItem("T-shirt", "Not found");
    addItem("Bread", "Food");
    addItem("Butter", "Food");
}

garbage.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<!-- Textview for heading -->
<TextView
    android:id="@+id/items"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<!-- Text field to enter item -->
<EditText
    android:id="@+id/edit_text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:inputType="text"
    android:layout_marginBottom="5dp"/>

<Button
    android:id="@+id/where_button"
    android:layout_width="wrap_content"
    android:layout_gravity="left"
    android:background="#39f208"
    android:text="Where"
    android:layout_height="80sp"/>

<Button
    android:id="@+id/add_button1"
    android:layout_width="wrap_content"
    android:layout_gravity="left"
    android:background="#39f208"
    android:text="Add an item"
    android:layout_height="80sp"/>
</LinearLayout>

garbage_activity.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TableLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <TextView
            android:id="@+id/textView5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="What Item?"
            android:textAppearance="@style/TextAppearance.AppCompat.Large" />

        <EditText
            android:id="@+id/what_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:inputType="textPersonName" />
    </TableRow>

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <TextView
            android:id="@+id/textView6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Where?"
            android:textAppearance="@style/TextAppearance.AppCompat.Large" />

        <EditText
            android:id="@+id/where_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="10"
            android:inputType="textPersonName" />
    </TableRow>

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <Button
            android:id="@+id/add_button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Add an Item" />
    </TableRow>
</TableLayout>
</LinearLayout>

这是我的第一个问题,请耐心等待 ;)

编辑 这是调试器日志:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: dk.itu.sortinggarbageapp, PID: 8926
java.lang.RuntimeException: Unable to start activity ComponentInfo{dk.itu.sortinggarbageapp/dk.itu.sortinggarbageapp.GarbageActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object java.util.Map.put(java.lang.Object, java.lang.Object)' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
    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:2066)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:223)
    at android.app.ActivityThread.main(ActivityThread.java:7656)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
 Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object java.util.Map.put(java.lang.Object, java.lang.Object)' on a null object reference
    at dk.itu.sortinggarbageapp.ItemsDB.addItem(ItemsDB.java:27)
    at dk.itu.sortinggarbageapp.ItemsDB.fillItemsDB(ItemsDB.java:40)
    at dk.itu.sortinggarbageapp.ItemsDB.<init>(ItemsDB.java:17)
    at dk.itu.sortinggarbageapp.ItemsDB.get(ItemsDB.java:21)
    at dk.itu.sortinggarbageapp.GarbageActivity.onCreate(GarbageActivity.java:24)
    at android.app.Activity.performCreate(Activity.java:8000)
    at android.app.Activity.performCreate(Activity.java:7984)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) 
    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:2066) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:223) 
    at android.app.ActivityThread.main(ActivityThread.java:7656) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.ja va:592) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 
I/Process: Sending signal. PID: 8926 SIG: 9
Disconnected from the target VM, address: 'localhost:63608',transport: 
'socket'

启动 activity 时使用的 ItemsDB 构造函数调用 fillItemsDB() 将项目添加到 ItemsDB 字段。但是,该字段未在此构造函数中初始化。

您需要在那里初始化它,调用另一个构造函数,或者在您声明字段的地方初始化。

// initialize at field declaration
Map<String, Item> ItemsDB = new HashMap<>();

// initialize here
private ItemsDB(Context context)  {
    ItemsDB = new HashMap<>();
    fillItemsDB();
}
// call the other constructor
public ItemsDB(Context context) {
    this();
    fillItemsDB();
}

这些都行。

你可以在你的垃圾上试试这个 class

ItemsDB itemsDB = new ItemsDB();
itemsDB.get(GarbageActivity.this);