2017-02-21 43 views
-1

我正在構建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

單身人士是你想要做的事情的反模式。另外,你已經有了數據庫,所以你有一個持久層 –

回答

0

問題是當onCreate發生時,您將刪除該對象,然後嘗試啓動其他活動或使用哈希表中的該鍵返回某個活動。此時,該對象已從散列表中消失。

您可以使用Parcelable對象和使用活動中onSaveInstanceStateonRestoreInstanceState方法,或Intent.putExtra以繞過Parcelable小號