Java.lang.IllegalStateException: Фрагмент не привязан к действию

Я редко получаю эту ошибку при вызове API.

java.lang.IllegalStateException: Fragment  not attached to Activity

Я попытался поместить код внутри метода isAdded(), чтобы проверить, добавлен ли фрагмент в свою активность, но все же я редко получаю эту ошибку. Я не понимаю, почему я все еще получаю эту ошибку. Как я могу предотвратить это?

Показана ошибка в строке -

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

Ниже приведен пример вызова 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();
                        }
                    }
                });

Ответ 1

Эта ошибка возникает из-за комбинированного эффекта двух факторов:

  • HTTP-запрос, когда он завершен, вызывает либо onResponse(), либо onError() (которые работают в основном потоке), не зная, остается ли Activity на переднем плане или нет. Если Activity ушел (пользователь перешел в другое место), getActivity() возвращает значение null.
  • Volley Response выражается как анонимный внутренний класс, который неявно содержит сильную ссылку на внешний класс Activity. Это приводит к классической утечке памяти.

Чтобы решить эту проблему, вы всегда должны:

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

    // etc ...

}

а также используйте 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();
        }
    }
}

Ответ 2

Жизненный цикл фрагментов очень сложный и полный ошибок, попробуйте добавить:

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

Ответ 3

Я нашел очень простое решение isAdded() метод, который является одним из методов фрагмента, чтобы идентифицировать, что этот текущий фрагмент привязан к его активности или нет.

мы можем использовать это как везде в классе фрагментов, например:

if(isAdded())
{

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

}

Ответ 4

Я могу опоздать, но может помочь кому-то..... Лучшее решение для этого - создать экземпляр глобального экземпляра приложения и вызвать его в конкретном фрагменте, в котором ваша активность не подключена.

как показано ниже

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

Вот класс приложения

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

Ответ 5

Эта ошибка может произойти, если вы создаете экземпляр фрагмента, который каким-то образом не может быть создан:

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

В моем случае я встретил это, когда попытался использовать:

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

Ответ 6

это происходит, когда фрагмент не имеет контекста, поэтому метод getActivity() возвращает значение null. проверьте, используете ли вы контекст, прежде чем вы его получите, или если активность больше не существует. использовать контекст в фрагменте .onCreate и после ответа api обычно в случае этой проблемы

Ответ 7

Иногда это исключение вызвано ошибкой в ​​реализации библиотеки поддержки. Недавно мне пришлось понизить с 26.1.0 до 25.4.0, чтобы избавиться от него.