我正在为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
却没有。
有人可以在这里解释实际问题吗?
答案 0 :(得分:0)
问题是您在onCreate
发生时删除了对象,然后尝试启动其他活动或使用哈希表中的该键返回某些活动。此时,对象从哈希表中消失。
您可以使用Parcelable
个对象,并使用活动中的onSaveInstanceState
和onRestoreInstanceState
方法,或Intent.putExtra
来传递Parcelable
个