1. 程式人生 > >解決在Fragment中getActivity()為空問題

解決在Fragment中getActivity()為空問題

最近在做使用網易雲信仿微信專案,在獲取最近聯絡人未讀訊息總數後需要重新整理底部提示數字,因為底部提示數字的控制元件在Activity中,獲取未讀訊息數的操作是在Fragment中(Fragment+ViewPager),在得到總未讀訊息數後需要更新activity中的控制元件顯示資訊,所以用到了getActivity(),但是得到NullPointException,通過debug得到getActivity()得到的是null。但是我在其他方法中又可以得到,經排查只要是在網易雲信的靜態方法回撥中使用getActivity()就會得到null。

/**
   * 監聽最近聯絡人
   */
  private
void observeRecentContact() { mMessageObserver = new Observer<List<RecentContact>>() { @Override public void onEvent(List<RecentContact> recentContacts) { if (recentContacts != null && recentContacts.size() > 0) { if
(mAdapter != null) mAdapter.setData(recentContacts); updateTotalUnReadCount();//這裡呼叫的方法中呼叫getActivity() } } }; NimRecentContactSDK.observeRecentContact(mMessageObserver, true); } /** * 更新未讀總數 */ private void updateTotalUnReadCount
() { int totalUnreadCount = NimRecentContactSDK.getTotalUnreadCount(); activity = (MainActivity) getActivity();//得到null if (totalUnreadCount > 0) { activity.mTvMessageCount.setVisibility(View.VISIBLE); activity.mTvMessageCount.setText(String.valueOf(totalUnreadCount)); } else { activity.mTvMessageCount.setVisibility(View.GONE); } }

通過觀察程式碼,我猜測網易雲信的介面回撥應該是在別的程序中執行的,而理論上getActivity()應該得到的是主執行緒的activity,但是程式碼中是在網易雲信的回撥中呼叫,也就是在別的程序中呼叫,故得不到activity。又因為getActivity()必須在生命週期onAttach與onDetach之間呼叫才有效,所以解決的辦法在onAttach中將上下文進行儲存,如下:

MainActivity activity;
@Override
   public void onAttach(Context context) {
       super.onAttach(context);
       activity = (MainActivity) context;//儲存Context引用
   }

這下問題解決了:

/**
 * 更新未讀總數
 */
private void updateTotalUnReadCount() {
    int totalUnreadCount = NimRecentContactSDK.getTotalUnreadCount();
    //activity = (MainActivity) getActivity();//activity在onAttach中儲存了
    if (totalUnreadCount > 0) {
        activity.mTvMessageCount.setVisibility(View.VISIBLE);
        activity.mTvMessageCount.setText(String.valueOf(totalUnreadCount));
    } else {
        activity.mTvMessageCount.setVisibility(View.GONE);
    }
}

總結:當遇到getActivity()為null,或getContext()時,先冷靜想想以下3點:

 1. 是不是放在了第三方的回撥中
 2. 是不是在其他程序中呼叫了(其實第一點就是在其他程序中呼叫了)
 3. 是不是呼叫時不在指定生命週期範圍內(onAttach與onDetach之間)

一般不是上述情況就不會得到null啦,如有不足,歡迎提出,謝謝。