Fragment getActivity()返回null

       在Fragment中使用AsyncHttpClient框架异步访问接口,在接口的回调中,刷新界面,调用getActivity()有时会出现nullPointer的情况,这是什么原因呢?

(一) getActivity() 什么时候返回空,什么时候不返回空?

       查看Fragment的getActivity()的代码:

   /**
     * Return the Activity this fragment is currently associated with.
     */
    final public Activity getActivity() {
        return mActivity;
    }

      返回的是Fragment的mActivity变量。

    // Activity this fragment is attached to.
    Activity mActivity;

       mActivity的初始化是在FragmentManager的moveToState()方法中。

case Fragment.INITIALIZING:
	if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
	if (f.mSavedFragmentState != null) {
		f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
				FragmentManagerImpl.VIEW_STATE_TAG);
		f.mTarget = getFragment(f.mSavedFragmentState,
				FragmentManagerImpl.TARGET_STATE_TAG);
		if (f.mTarget != null) {
			f.mTargetRequestCode = f.mSavedFragmentState.getInt(
					FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
		}
		f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
				FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
		if (!f.mUserVisibleHint) {
			f.mDeferStart = true;
			if (newState > Fragment.STOPPED) {
				newState = Fragment.STOPPED;
			}
		}
	}
	f.mActivity = mActivity;
        f.mParentFragment = mParent;
	f.mFragmentManager = mParent != null
			? mParent.mChildFragmentManager : mActivity.mFragments;
	f.mCalled = false;
	f.onAttach(mActivity);
	if (!f.mCalled) {
		throw new SuperNotCalledException("Fragment " + f
				+ " did not call through to super.onAttach()");
	}
	if (f.mParentFragment == null) {
		mActivity.onAttachFragment(f);
	}

	if (!f.mRetaining) {
		f.performCreate(f.mSavedFragmentState);
	}
	f.mRetaining = false;
	if (f.mFromLayout) {
		// For fragments that are part of the content view
		// layout, we need to instantiate the view immediately
		// and the inflater will take care of adding it.
		f.mView = f.performCreateView(f.getLayoutInflater(
				f.mSavedFragmentState), null, f.mSavedFragmentState);
		if (f.mView != null) {
			f.mView.setSaveFromParentEnabled(false);
			if (f.mHidden) f.mView.setVisibility(View.GONE);
			f.onViewCreated(f.mView, f.mSavedFragmentState);
		}
	}

       可以看到,f.mActivity在Fragment的初始化阶段被初始化为FragmentManager的mActivity变量,之后依次调用了f.onAttach()、f.perfomCreate()(里面调用了onCreate())、f.performCreateView() (里面调用了onCreateView())、f.onViewCreated()等回调方法。

       至于f.mActivity被置空也是在FragmentManager的moveToState()方法里。

    case Fragment.CREATED:
       	if (newState < Fragment.CREATED) {
		if (mDestroyed) {
			if (f.mAnimatingAway != null) {
				// The fragment's containing activity is
				// being destroyed, but this fragment is
				// currently animating away.  Stop the
				// animation right now -- it is not needed,
				// and we can't wait any more on destroying
				// the fragment.
				Animator anim = f.mAnimatingAway;
				f.mAnimatingAway = null;
				anim.cancel();
			}
		}
		if (f.mAnimatingAway != null) {
			// We are waiting for the fragment's view to finish
			// animating away.  Just make a note of the state
			// the fragment now should move to once the animation
			// is done.
			f.mStateAfterAnimating = newState;
			newState = Fragment.CREATED;
		} else {
			if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f);
			if (!f.mRetaining) {
				f.performDestroy();
			}

			f.mCalled = false;
			f.onDetach();
			if (!f.mCalled) {
				throw new SuperNotCalledException("Fragment " + f
						+ " did not call through to super.onDetach()");
			}
			if (!keepActive) {
				if (!f.mRetaining) {
					makeInactive(f);
				} else {
					f.mActivity = null;
					f.mParentFragment = null;
					f.mFragmentManager = null;
				}
			}
		}
	}

        可以看到,f.mActivity的置空操作是在Fragment销毁阶段,在onDetach()回调之后。

        因此,在Fragment的回调生命周期中,getActivity()都不会返回空。getActivity()为空表明,AsyncHttpClient的回调是在Fragment销毁后,才开始执行的。

 

(二)AsyncHttpClient异步请求的回调

         AsyncHttpClient异步请求是在内部的线程池中运行的,回调是在通过Looper线程的Handler传回发起调用的线程执行。此时,有可能出现页面、Fragment已经被销毁的情况,从而getActivity()返回null。

        解决方案是:在页面退出时,取消正在发起的请求;在回调中,做与UI相关的操作,需要对Activity进行判断(getActivity() != null && !getActivity.isFinish())。

       


               

你可能感兴趣的:(android,多线程)