简体   繁体   English

java.lang.IllegalStateException:片段未附加到活动

[英]java.lang.IllegalStateException: Fragment not attached to Activity

I am rarely getting this error while making an API call.在进行 API 调用时,我很少遇到此错误。

java.lang.IllegalStateException: Fragment  not attached to Activity

I tried putting the code inside isAdded() method to check whether fragment is currently added to its activity but still i rarely gets this error.我尝试将代码放入isAdded()方法中以检查片段当前是否已添加到其活动中,但我仍然很少收到此错误。 I fail to understand why I am still getting this error.我不明白为什么我仍然收到此错误。 How can i prevent it?我该如何预防?

Its showing error on the line-它在行上显示错误-

cameraInfo.setId(getResources().getString(R.string.camera_id));

Below is the sample api call that i am making.下面是我正在进行的示例 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();
                        }
                    }
                });

This error happens due to the combined effect of two factors:发生此错误是由于两个因素的综合影响:

  • The HTTP request, when complete, invokes either onResponse() or onError() (which work on the main thread) without knowing whether the Activity is still in the foreground or not. HTTP 请求在完成时调用onResponse()onError() (在主线程上工作),而无需知道Activity是否仍在前台。 If the Activity is gone (the user navigated elsewhere), getActivity() returns null.如果Activity消失了(用户导航到其他地方), getActivity()返回 null。
  • The Volley Response is expressed as an anonymous inner class, which implicitly holds a strong reference to the outer Activity class. Volley Response表示为匿名内部类,它隐式地持有对外部Activity类的强引用。 This results in a classic memory leak.这会导致典型的内存泄漏。

To solve this problem, you should always do:要解决此问题,您应该始终执行以下操作:

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

    // etc ...

}

and also, use isAdded() in the onError() method as well:此外,在onError()方法中也使用isAdded()

@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();
        }
    }
}

Fragment lifecycle is very complex and full of bugs, try to add: Fragment生命周期很复杂,bug很多,尝试补充:

Activity activity = getActivity(); 
if (isAdded() && activity != null) {
...
}

I Found Very Simple Solution isAdded() method which is one of the fragment method to identify that this current fragment is attached to its Activity or not.我发现非常简单的解决方案isAdded()方法是一种片段方法,用于识别当前片段是否附加到其活动。

we can use this like everywhere in fragment class like:我们可以在片段类中的任何地方使用它,例如:

if(isAdded())
{

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

}

Exception: java.lang.IllegalStateException: Fragment异常: java.lang.IllegalStateException:片段

DeadlineListFragment{ad2ef970} not attached to Activity DeadlineListFragment{ad2ef970} 未附加到活动

Category: Lifecycle类别:生命周期

Description : When doing time-consuming operation in background thread(eg, AsyncTask), a new Fragment has been created in the meantime, and was detached to the Activity before the background thread finished.说明:在后台线程(如AsyncTask)中进行耗时操作时,同时创建了一个新的Fragment,并在后台线程完成之前分离到Activity。 The code in UI thread(eg,onPostExecute) calls upon a detached Fragment, throwing such exception. UI 线程中的代码(例如,onPostExecute)调用分离的 Fragment,抛出此类异常。

Fix solution:修复解决方案:

  1. Cancel the background thread when pausing or stopping the Fragment暂停或停止 Fragment 时取消后台线程

  2. Use isAdded() to check whether the fragment is attached and then to getResources() from activity.使用 isAdded() 检查是否已附加片段,然后从活动中获取 getResources()。

i may be late but may help someone ..... The best solution for this is to create a global application class instance and call it in the particular fragment where your activity is not being attached我可能会迟到,但可能会帮助某人..... 最好的解决方案是创建一个全局应用程序类实例,并在没有附加您的活动的特定片段中调用它

as like below如下

icon = MyApplication.getInstance().getString(R.string.weather_thunder);

Here is application class这是应用程序类

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;
    }
}

In Fragment use isAdded() It will return true if the fragment is currently attached to Activity.在片段中使用isAdded()如果片段当前附加到 Activity ,它将返回 true。

If you want to check inside the Activity如果您想检查活动内部

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

Hope it will help someone希望它会帮助某人

This error can happen if you are instantiating a fragment that somehow can't be instantiated:如果您正在实例化一个无法实例化的片段,则可能会发生此错误:

Fragment myFragment = MyFragment.NewInstance();


public classs MyFragment extends Fragment {
  public void onCreate() {
   // Some error here, or anywhere inside the class is preventing it from being instantiated
  }
}

In my case, i have met this when i tried to use:就我而言,当我尝试使用时遇到了这个问题:

private String loading = getString(R.string.loading);

I adopted the following approach for handling this issue.我采用了以下方法来处理这个问题。 Created a new class which act as a wrapper for activity methods like this创建了一个新类,它充当这样的活动方法的包装器

public class ContextWrapper {
    public static String getString(Activity activity, int resourceId, String defaultValue) {
        if (activity != null) {
            return activity.getString(resourceId);
        } else {
            return defaultValue;
        }
    }

    //similar methods like getDrawable(), getResources() etc

}

Now wherever I need to access resources from fragments or activities, instead of directly calling the method, I use this class.现在无论我需要从片段或活动访问资源,而不是直接调用方法,我都使用这个类。 In case the activity context is not null it returns the value of the asset and in case the context is null, it passes a default value (which is also specified by the caller of the function).如果活动context不为null它返回资产的值,如果context为空,它传递一个默认值(这也是由函数调用者指定的)。

Important This is not a solution, this is an effective way where you can handle this crash gracefully.重要这不是解决方案,而是一种可以优雅地处理此崩溃的有效方法。 You would want to add some logs in cases where you are getting activity instance as null and try to fix that, if possible.如果您将活动实例设为空,您可能希望添加一些日志并尝试修复该问题(如果可能)。

this happen when the fragment does not have a context ,thus the getActivity()method return null.当片段没有上下文时会发生这种情况,因此 getActivity() 方法返回 null。 check if you use the context before you get it,or if the Activity is not exist anymore .在获取上下文之前检查是否使用了上下文,或者该 Activity 是否已不存在。 use context in fragment.onCreate and after api response usually case this problem在 fragment.onCreate 和 api 响应之后使用上下文通常会解决这个问题

Sometimes this exception is caused by a bug in the support library implementation.有时此异常是由支持库实现中的错误引起的。 Recently I had to downgrade from 26.1.0 to 25.4.0 to get rid of it.最近我不得不从 26.1.0 降级到 25.4.0 才能摆脱它。

This issue occurs whenever you call a context which is unavailable or null when you call it.每当您调用一个不可用或 null 的上下文时,就会出现此问题。 This can be a situation when you are calling main activity thread's context on a background thread or background thread's context on main activity thread.当您在后台线程上调用主活动线程的上下文或在主活动线程上调用后台线程的上下文时,可能会出现这种情况。

For instance , I updated my shared preference string like following.例如,我更新了我的共享首选项字符串,如下所示。

editor.putString("penname",penNameEditeText.getText().toString());
editor.commit();
finish();

And called finish() right after it.并在它之后立即调用finish()。 Now what it does is that as commit runs on main thread and stops any other Async commits if coming until it finishes.现在它所做的是,当提交在主线程上运行并停止任何其他异步提交时,直到它完成。 So its context is alive until the write is completed.所以它的上下文一直存在,直到写入完成。 Hence previous context is live , causing the error to occur.因此以前的上下文是 live ,导致错误发生。

So make sure to have your code rechecked if there is some code having this context issue.因此,如果某些代码存在此上下文问题,请确保重新检查您的代码。

So the base idea is that you are running a UI operation on a fragment that is getting in the onDetach lifecycle.因此,基本思想是您正在对进入onDetach生命周期的片段运行UI 操作

When this is happening the fragment is getting off the stack and losing the context of the Activity .发生这种情况时,片段正在脱离堆栈并丢失Activity的上下文。

So when you call UI related functions for example calling the progress spinner and you want to leave the fragment check if the Fragment is added to the stack, like this:因此,当您调用 UI 相关函数时,例如调用进度微调器,并且您想离开 Fragment 检查是否将 Fragment 添加到堆栈中,如下所示:

if(isAdded){ progressBar.visibility=View.VISIBLE }

This will solve your problem.这将解决您的问题。

Add This on your Fragemnt将此添加到您的 Fragment

Activity activity;
@Override
public void onAttach(@NonNull Context context) {
    super.onAttach(context);
    activity = context instanceof Activity ? (Activity) context : null;
}

Then change getContext(), getActivity(), requireActivity() or requireContext() with activity然后用activity改变getContext()、getActivity()、requireActivity()或requireContext()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 java.lang.IllegalStateException片段未附加到活动 - java.lang.IllegalStateException Fragment not attached to Activity java.lang.IllegalStateException:片段未附加到android中的Activity问题 - java.lang.IllegalStateException: Fragment not attached to Activity issue in android java.lang.IllegalStateException:片段未附加到 Android 中的活动 - java.lang.IllegalStateException: Fragment not attached to Activity in Android java.lang.IllegalStateException:片段未附加到上下文 - java.lang.IllegalStateException: Fragment not attached to a context java.lang.IllegalStateException:API响应后,片段未附加到上下文 - java.lang.IllegalStateException: Fragment not attached to a context after API response android - java.lang.IllegalStateException:片段未附加到上下文 - android - java.lang.IllegalStateException: Fragment not attached to a context 如何修复 java.lang.IllegalStateException:片段未附加到上下文 - How to fix java.lang.IllegalStateException: Fragment not attached to a context 无法启动活动ComponentInfo ... java.lang.IllegalStateException:已经附加 - Unable to start activity ComponentInfo…java.lang.IllegalStateException: Already attached 片段中的 java.lang.IllegalStateException - java.lang.IllegalStateException in fragment java.lang.IllegalStateException:Fragment - java.lang.IllegalStateException: Fragment
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM