解决在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啦,如有不足,欢迎提出,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值