java.lang.IllegalStateException: Fragment not attached to Activity

北城余情 提交于 2019-12-27 16:34:27

问题


I am rarely getting this error while making an API call.

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. 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.

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

回答1:


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. If the Activity is gone (the user navigated elsewhere), getActivity() returns null.
  • The Volley Response is expressed as an anonymous inner class, which implicitly holds a strong reference to the outer Activity class. 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:

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



回答2:


Fragment lifecycle is very complex and full of bugs, try to add:

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



回答3:


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.

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.

}



回答4:


Exception: java.lang.IllegalStateException: Fragment

DeadlineListFragment{ad2ef970} not attached to Activity

Category: Lifecycle

Description: When doing time-consuming operation in background thread(e.g, AsyncTask), a new Fragment has been created in the meantime, and was detached to the Activity before the background thread finished. The code in UI thread(e.g.,onPostExecute) calls upon a detached Fragment, throwing such exception.

Fix solution:

  1. Cancel the background thread when pausing or stopping the Fragment

  2. Use isAdded() to check whether the fragment is attached and then to getResources() from activity.




回答5:


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



回答6:


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



回答7:


In Fragment use isAdded() It will return true if the fragment is currently attached to Activity.

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




回答8:


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).

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.




回答9:


this happen when the fragment does not have a context ,thus the getActivity()method return null. check if you use the context before you get it,or if the Activity is not exist anymore . use context in fragment.onCreate and after api response usually case this problem




回答10:


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.




回答11:


This issue occurs whenever you call a context which is unavailable or null when you call it. 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. 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.

So make sure to have your code rechecked if there is some code having this context issue.



来源:https://stackoverflow.com/questions/28672883/java-lang-illegalstateexception-fragment-not-attached-to-activity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!