it-swarm.com.ru

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

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

  • После завершения HTTP-запроса вызывается onResponse() или onError() (которые работают в основном потоке), не зная, находится ли Activity на переднем плане или нет. Если Activity пропал (пользователь переместился в другое место), getActivity() возвращает ноль.
  • Залп 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();
        }
    }
}
169
Y.S.

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

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

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

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

if(isAdded())
{

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

}
11
Dharmesh Baldha

Исключение: Java.lang.IllegalStateException: фрагмент

DeadlineListFragment {ad2ef970} не присоединен к Activity

Категория: Жизненный цикл

Описание : При выполнении длительной операции в фоновом потоке (например, AsyncTask) тем временем был создан новый фрагмент, который был отсоединен от действия до завершения фонового потока. Код в потоке пользовательского интерфейса (например, onPostExecute) вызывает отдельный фрагмент, вызывая такое исключение.

Исправить решение:

  1. Отмените фоновый поток при приостановке или остановке фрагмента

  2. Используйте isAdded (), чтобы проверить, прикреплен ли фрагмент , А затем получить getResources () из действия.

8
Rahil Ali

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

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

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

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

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

Во фрагменте используйте isAdded() Он вернет true, если фрагмент в настоящее время присоединен к Activity.

Если вы хотите проверить внутри деятельности

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

Надеюсь, это поможет кому-то

2
Prateek218

Я принял следующий подход для решения этой проблемы. Создан новый класс, который действует как обертка для таких методов деятельности

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

}

Теперь, где бы мне ни понадобился доступ к ресурсам из фрагментов или действий, вместо прямого вызова метода, я использую этот класс. Если действие context не является null, оно возвращает значение актива, а если context имеет значение null, оно передает значение по умолчанию (которое также указывается вызывающей функцией).

Важно Это не решение, это эффективный способ, где вы можете изящно справиться с этим сбоем. Вы хотели бы добавить несколько журналов в тех случаях, когда вы получаете экземпляр активности как нулевой, и попытаться исправить это, если это возможно.

1
Ezio

Эта проблема возникает всякий раз, когда вы вызываете контекст, который недоступен или имеет значение null при его вызове. Это может быть ситуация, когда вы вызываете контекст основного потока активности в фоновом потоке или контекст фонового потока в основном потоке активности.

Например, я обновил свою общую строку настроек следующим образом.

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

И вызвал finish () сразу после него. Теперь он выполняет коммит в основном потоке и останавливает любые другие асинхронные коммиты, если поступает, пока не завершится. Таким образом, его контекст жив, пока запись не завершена. Следовательно, предыдущий контекст является живым, вызывая ошибку.

Поэтому убедитесь, что ваш код перепроверен, если есть какой-то код, имеющий эту проблему контекста. 

0
Prashant Paliwal

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

0
Bord81

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

0
dexian fan