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();
}
}
});
이 오류는 두 가지 요소의 결합 된 효과로 인해 발생합니다.
- HTTP 요청이 완료되면가 여전히 포 그라운드에 있는지 여부를 모르고
onResponse()
또는onError()
(메인 스레드에서 작동하는) 호출합니다Activity
. 이 경우Activity
(사용자가 다른 곳에서 탐색) 사라,getActivity()
NULL을 반환합니다. - 발리
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();
}
}
}
조각 수명주기는 매우 복잡하고 버그로 가득 차 있습니다.
Activity activity = getActivity();
if (isAdded() && activity != null) {
...
}
매우 간단한 해결책을 찾았습니다. 현재 조각이 해당 활동에 첨부되어 있는지 여부를 식별하는 조각 방법 중 하나 인 iBug () 메서드입니다.
우리는 다음과 같이 프래그먼트 클래스의 모든 곳에서 이것을 사용할 수 있습니다 :
if(isAdded())
{
// using this method, we can do whatever we want which will prevent **java.lang.IllegalStateException: Fragment not attached to Activity** exception.
}
예외 : java.lang.IllegalStateException : 단편
DeadlineListFragment {ad2ef970}이 활동에 첨부되지 않았습니다
카테고리 : 라이프 사이클
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:
Cancel the background thread when pausing or stopping the Fragment
Use isAdded() to check whether the fragment is attached and then to getResources() from activity.
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;
}
}
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);
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
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.
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
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.
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.
'Programming' 카테고리의 다른 글
개인 순수 가상 기능의 요점은 무엇입니까? (0) | 2020.06.27 |
---|---|
초를 표시하지 않고 .toLocaleTimeString ()을 어떻게 사용합니까? (0) | 2020.06.27 |
경고 : refname 'HEAD'가 모호합니다. (0) | 2020.06.27 |
삽입 후 생성 된 아이디 얻기 (0) | 2020.06.27 |
jQuery UI 대화 상자를 ajax 가로 드 한 내용의 너비로 자동 크기 조정 (0) | 2020.06.27 |