getActivity()在Fragment函数中返回null

我有一个像这样的公共方法的片段(F1)

public void asd() { if (getActivity() == null) { Log.d("yes","it is null"); } } 

是的,当我调用它(从活动),它是空的…

 FragmentTransaction transaction1 = getSupportFragmentManager().beginTransaction(); F1 f1 = new F1(); transaction1.replace(R.id.upperPart, f1); transaction1.commit(); f1.asd(); 

这肯定是我做错了,但我不知道那是什么

commit调度事务,即它不会直接发生,而是在下一次主线程准备就绪时作为主线程工作。

我build议添加一个

 onAttach(Activity activity) 

方法到你的Fragment并把它放在一个断点,看看什么时候被称为相对于你的调用asd() 。 您会看到,在调用asd()退出之后调用它。 onAttach调用是Fragment附加到它的活动的地方,从这一点getActivity()将返回非null(也有一个onDetach()调用)。

最好摆脱这个是在onAttach被调用时保持活动引用,并在需要的地方使用活动引用,例如

 @Override public void onAttach(Activity activity) { super.onAttach(activity); mActivity = activity; } 

在另一个线程中调用getActivity() ,发生了这种情况。 典型的情况是在HTTP请求完成时(例如onResponse getActivity()调用getActivity() (例如Toast )。

为了避免这种情况,您可以定义一个字段名称mActivity并使用它来代替getActivity() 。 这个字段可以在Fragment的onAttach()方法中初始化如下:

 @Override public void onAttach(Activity activity) { super.onAttach(activity); mActivity = activity; } 

在我的项目中,我通常使用这个特性为我所有的片段定义一个基类:

 public abstract class BaseFragment extends Fragment { protected FragmentActivity mActivity; @Override public void onAttach(Activity activity) { super.onAttach(activity); mActivity = (FragmentActivity) activity; } } 

快乐的编码,

PJL是对的。 我用他的build议,这是我所做的:

  1. 为片段定义全局variables:

    private final Object attachingActivityLock = new Object();

    private boolean syncVariable = false;

  2. 实施

 @Override public void onAttach(Activity activity) { super.onAttach(activity); synchronized (attachingActivityLock) { syncVariable = true; attachingActivityLock.notifyAll(); } } 

3。 我包装了我的函数,我需要在线程中调用getActivity(),因为如果它将在主线程上运行,我会阻止步骤4的线程和onAttach()永远不会被调用。

  Thread processImage = new Thread(new Runnable() { @Override public void run() { processImage(); } }); processImage.start(); 

4。 在我需要调用getActivity()的函数中,我使用了这个(在调用getActivity()之前)

  synchronized (attachingActivityLock) { while(!syncVariable){ try { attachingActivityLock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 

如果你有一些UI更新,记得在UI线程上运行它们。 我需要更新ImgeView,所以我做了:

 image.post(new Runnable() { @Override public void run() { image.setImageBitmap(imageToShow); } }); 

由于Android API级别23,onAttach(Activity activity)已被弃用。 你需要使用onAttach(Context context)。 http://developer.android.com/reference/android/app/Fragment.html#onAttach(android.app.Activity);

活动是一个上下文,所以如果你可以简单地检查上下文是一个活动,并在必要时进行转换。

 @Override public void onAttach(Context context) { super.onAttach(context); Activity a; if (context instanceof Activity){ a=(Activity) context; } } 

commit()之后调用callback的顺序:

  1. 无论您在commit()后手动调用什么方法
  2. onAttach()
  3. onCreateView()
  4. onActivityCreated()

我需要做一些涉及一些视图的工作,所以对Attack()不适合我。 它坠毁。 所以我移动了一部分代码,在一个叫做commit()(1)之后的方法中设置了一些参数,然后是在onCreateView()(3.)内部处理视图的代码的另一部分。

做如下。 我认为这对你有帮助。

 private boolean isVisibleToUser = false; private boolean isExecutedOnce = false; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_my, container, false); if (isVisibleToUser && !isExecutedOnce) { executeWithActivity(getActivity()); } return root; } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); this.isVisibleToUser = isVisibleToUser; if (isVisibleToUser && getActivity()!=null) { isExecutedOnce =true; executeWithActivity(getActivity()); } } private void executeWithActivity(Activity activity){ //Do what you have to do when page is loaded with activity } 

你在哪里叫这个function? 如果你在Fragment的构造函数中调用它,它将返回null

只要在方法onCreateView()执行时调用getActivity()

其他答案build议保持对onAttach中的活动的参考仅仅是为真正的问题提供一个bandaid。 当getActivity返回null时,意味着Fragment没有附加到Activity。 最常见的情况是当Activity由于旋转或活动完成而消失的时候,但是Fragment有一些callback监听器。 当监听者被调用时,如果你需要对Activity执行某些操作,但Activity没有了,那么你可以做的事情就不多了。 在你的代码中,你应该检查getActivity() != null ,如果它不存在,那么不要做任何事情。 如果您保留对活动不存在的引用,则会阻止“活动”被垃圾收集。 用户可能不会看到任何您可能尝试执行的UI操作。 我可以想象一些情况,在callback监听器中你可能想要一个与UI非相关的Context,在这种情况下,获取Application上下文可能更有意义。 请注意, onAttach技巧不是一个大的内存泄漏的唯一原因是因为通常在callback监听器执行后,将不再需要它,可以随着Fragment,它的所有View和Activity上下文一起被垃圾回收。 如果你设置了setRetainInstance(true) ,那么内存泄漏的机会就会更大,因为Activity字段也会被保留,但是在setRetainInstance(true)之后可能会是前一个Activity而不是当前Activity。

那些仍然有onAttach(活动活动)的问题,它只是改变了上下文 –

  @Override public void onAttach(Context context) { super.onAttach(context); this.context = context; } 

在大多数情况下,保存上下文对于您来说已经足够了 – 例如,如果您想要执行getResources(),则可以直接从上下文中执行。 如果您仍然需要将上下文放入您的“活动”中,

  @Override public void onAttach(Context context) { super.onAttach(context); mActivity a; //Your activity class - will probably be a global var. if (context instanceof mActivity){ a=(mActivity) context; } } 

如user1868713所示。

最好和坚实的方法:

 FragmentActivity activity = (FragmentActivity) getActivity(); activity.finish();