java.lang.IllegalStateException:未附加到Activity的片段

And*_*per 140 android illegalstateexception android-fragments android-activity android-volley

在进行API调用时,我很少收到此错误.

java.lang.IllegalStateException: Fragment  not attached to Activity
Run Code Online (Sandbox Code Playgroud)

我尝试将代码放在isAdded()方法中以检查片段当前是否已添加到其活动中但仍然很少出现此错误.我不明白为什么我仍然会收到此错误.我怎么能阻止它?

它在线上显示错误 -

cameraInfo.setId(getResources().getString(R.string.camera_id));
Run Code Online (Sandbox Code Playgroud)

下面是我正在制作的示例api调用.

SAPI.getInfo(getActivity(),
                new APIResponseListener() {
                    @Override
                    public void onResponse(Object response) {


                        cameraInfo = new SInfo();
                        if(isAdded()) {
                            cameraInfo.setId(getResources().getString(R.string.camera_id));
                            cameraInfo.setName(getResources().getString(R.string.camera_name));
                            cameraInfo.setColor(getResources().getString(R.string.camera_color));
                            cameraInfo.setEnabled(true);
                        }


                    }

                    @Override
                    public void onError(VolleyError error) {
                        mProgressDialog.setVisibility(View.GONE);
                        if (error instanceof NoConnectionError) {
                            String errormsg = getResources().getString(R.string.no_internet_error_msg);
                            Toast.makeText(getActivity(), errormsg, Toast.LENGTH_LONG).show();
                        }
                    }
                });
Run Code Online (Sandbox Code Playgroud)

Y.S*_*Y.S 191

由于两个因素的综合影响,会发生此错误:

  • HTTP请求完成后,调用onResponse()或者onError()(在主线程上工作),而不知道它是否Activity仍然在前台.如果Activity已经消失(用户在别处导航),则getActivity()返回null.
  • Volley Response被表达为一个匿名的内部类,它隐含地强烈引用外部Activity类.这导致经典的内存泄漏.

要解决这个问题,你应该总是这样做:

Activity activity = getActivity();
if(activity != null){

    // etc ...

}
Run Code Online (Sandbox Code Playgroud)

并且,也用于isAdded()onError()方法:

@Override
public void onError(VolleyError error) {

    Activity activity = getActivity(); 
    if(activity != null && isAdded())
        mProgressDialog.setVisibility(View.GONE);
        if (error instanceof NoConnectionError) {
           String errormsg = getResources().getString(R.string.no_internet_error_msg);
           Toast.makeText(activity, errormsg, Toast.LENGTH_LONG).show();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • isAdded()就足够了,final public boolean isAdded(){return mActivity!= null && mAdded; } (4认同)
  • 当从“活动”中使用Volley请求和“ AsyncTask”时,没有万无一失的方法可以避免NPE。当线程之一在后台做某事时,当线程完成并调用onPostExecute()或onResponse()时,用户总是有机会离开当前的“活动”。没有“活动”。您所能做的就是在代码中的各个点检查空引用,这不是防弹的:) (2认同)
  • 如果你还没有以通用/全局方式解释它,那么android猴子测试(adb shell monkey)真的很擅长根除这个错误. (2认同)
  • @ruselli:检查`added`布尔标志以及当前`Activity`实例是否为`null`. (2认同)

Mir*_*lec 50

片段生命周期非常复杂且充满了bug,尝试添加:

Activity activity = getActivity(); 
if (isAdded() && activity != null) {
...
}
Run Code Online (Sandbox Code Playgroud)

  • 我应该把它放在哪里? (2认同)
  • 如果activity == null我应该怎么做。保持我的应用程序@Miroslav (2认同)

小智 14

我发现非常简单的解决方案 isAdded()方法,它是一种片段方法,用于识别此当前片段是否附加到其Activity.

我们可以在片段类中随处使用它,如:

if(isAdded())
{

// using this method, we can do whatever we want which will prevent   **java.lang.IllegalStateException: Fragment not attached to Activity** exception.

}
Run Code Online (Sandbox Code Playgroud)


Rah*_*Ali 10

例外: java.lang.IllegalStateException:Fragment

DeadlineListFragment {ad2ef970}未附加到Activity

类别:生命周期

描述:在后台线程(例如,AsyncTask)中执行耗时的操作时,同时创建了一个新的Fragment,并在后台线程完成之前将其分离到Activity.UI线程中的代码(例如,onPostExecute)调用分离的片段,抛出此类异常.

修复方案:

  1. 暂停或停止片段时取消后台线程

  2. 使用isAdded()检查片段是否已附加,然后从活动中检查getResources().


md *_*use 8

我可能会迟到但可能会帮助某人......对此最好的解决方案是创建一个全局应用程序类实例并在未附加活动的特定片段中调用它

如下所示

icon = MyApplication.getInstance().getString(R.string.weather_thunder);
Run Code Online (Sandbox Code Playgroud)

这是应用程序类

public class MyApplication extends Application {

    private static MyApplication mInstance;
    private RequestQueue mRequestQueue;

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }

    public static synchronized MyApplication getInstance() {
        return mInstance;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这不是明智的选择。FragmentContext 和 ApplicationContext 具有不同的样式。片段上下文可能有深色主题、自定义样式、区域设置等。这将从不同文件中提取颜色、字符串资源。虽然 ApplicationContext 可能无法提取正确的资源。如果您没有上下文,那么您不应该尝试渲染该资源。 (2认同)

Pra*_*218 5

在Fragment中使用isAdded() 如果fragment当前附加到Activity,它将返回true。

如果你想检查 Activity 内部

 Fragment fragment = new MyFragment();
   if(fragment.getActivity()!=null)
      { // your code here}
      else{
       //do something
       }
Run Code Online (Sandbox Code Playgroud)

希望它能帮助某人