使用HashTable在活动之间传递数据

时间:2017-02-21 01:36:51

标签: java android nullpointerexception

我正在为Android构建一个笔记应用程序。 为了减轻活动之间共享价值(数据/对象)的痛苦,我写了一个 IntentHelper 类,它在<key,object>中存储HashTable对。

public class IntentHelper {
    private static IntentHelper _instance;
    private static Hashtable<String, Object> _hash;


    private IntentHelper() {
        _hash = new Hashtable<>();
    }

    public static IntentHelper getInstance() {
        if (_instance == null) {
            _instance = new IntentHelper();
        }
        return _instance;
    }

    public static void addObjectForKey(Object obj, String key) {
        getInstance()._hash.put(key, obj);
    }

    public static Object getObjectForKey(String key) {
        IntentHelper helper = getInstance();
        Object data = helper._hash.get(key);
        helper._hash.remove(key);
        helper = null;
        return data;
    }
}

如果查看IntentHelper类,它还会在检索HashTable后从HashTable中删除<key, object>对。这只是为了优化。

Note是一个带有String成员变量的Java POJO。

使用IntentHelper,我在两个活动之间传递Note对象,但是当我运行应用程序时,它崩溃并出现错误:

java.lang.RuntimeException: Unable to resume activity {co.kodr.note/co.kodr.note.activity.NoteViewActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String co.kodr.note.model.Note.getNoteDescription()' on a null object reference
                      at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3103)
                      at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2481)
                      at android.app.ActivityThread.-wrap11(ActivityThread.java)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:148)
                      at android.app.ActivityThread.main(ActivityThread.java:5417)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                   Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String co.kodr.note.model.Note.getNoteDescription()' on a null object reference
                      at co.kodr.note.activity.NoteViewActivity.reDrawView(NoteViewActivity.java:47)
                      at co.kodr.note.activity.NoteViewActivity.onResume(NoteViewActivity.java:54)

当我调试应用程序时,我可以看到从IntentHelper检索的Note对象是非null。以下是2项活动:

MainActivity

public class MainActivity extends AppCompatActivity {


    Note note;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.single_note_toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayShowTitleEnabled(false);
        reDrawNoteList();
    }

    private void reDrawNoteList() {

        Cursor cursor = Utils.readFromDatabase(this, Constants.SELECT_ALL_NOTES);

        ListView notesList = (ListView) findViewById(R.id.noteList);
        NoteCursorAdapter noteCursorAdapter = new NoteCursorAdapter(this, cursor);
        notesList.setAdapter(noteCursorAdapter);

        notesList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                note = (Note) view.getTag();
                startNoteViewActivity();
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        reDrawNoteList();
    }

    private void startNoteViewActivity(){
        IntentHelper.getInstance().addObjectForKey(note, Constants.SINGLE_NOTE);
        Intent note_view_intent = new Intent(MainActivity.this, NoteViewActivity.class);
        startActivity(note_view_intent);
    }
}

NoteViewActivity

public class NoteViewActivity extends AppCompatActivity {
    Note note;
    private CustomTextView noteTitle;
    private CustomTextView noteText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_note_view);
        Toolbar toolbar = (Toolbar) findViewById(R.id.single_note_toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayShowTitleEnabled(false);

        noteTitle = (CustomTextView) findViewById(R.id.tv_NoteDescription);
        noteText = (CustomTextView) findViewById(R.id.tv_NoteText);

        reDrawView();

    }

    private void reDrawView(){

        note = (Note) IntentHelper.getObjectForKey(Constants.SINGLE_NOTE);

        noteTitle.setText(note.getNoteDescription());
        noteText.setText(note.getNoteText());
    }

    @Override
    protected void onResume() {
        super.onResume();
        reDrawView();
    }
}

我知道问题在某种程度上是在检索它时删除<key, value>对,因为我可以通过注释来阻止应用崩溃:

helper._hash.remove(key);

问题出现在新推出的应用(onCreate)以及OnResume上。我可以在OnResume中看到它发生的原因,但OnCreate却没有。

有人可以在这里解释实际问题吗?

1 个答案:

答案 0 :(得分:0)

问题是您在onCreate发生时删除了对象,然后尝试启动其他活动或使用哈希表中的该键返回某些活动。此时,对象从哈希表中消失。

您可以使用Parcelable个对象,并使用活动中的onSaveInstanceStateonRestoreInstanceState方法,或Intent.putExtra来传递Parcelable