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

问题描述:

我正在构建Android的笔记应用程序。为了缓解活动之间共享价值(数据/对象)的痛苦,我写了一个IntentHelper类,其中存储<key,object>HashTable使用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类,它也取回后,将删除哈希表中的<key, object>对。这只是为了优化。

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

使用IntentHelper,我沿着活动Note对象之间的2传球,但是当我运行程序的时候,出现错误崩溃:

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) 

当我调试应用程序,我可以看到Note对象从IntentHelper检索不为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

单身哈希表似乎是一个贫穷的想法。使用parcelable在intent之间正确地移动数据 –

+0

@ cricket_007单身散列表的任何特定问题? – Anurag

+0

单身人士是你想要做的事情的反模式。另外,你已经有了数据库,所以你有一个持久层 –

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

您可以使用Parcelable对象和使用活动中onSaveInstanceStateonRestoreInstanceState方法,或Intent.putExtra以绕过Parcelable小号