java.lang.IllegalStateException:片段未附加到 Activity
java.lang.IllegalStateException: Fragment not attached to Activity
我在拨打 API 电话时很少遇到此错误。
java.lang.IllegalStateException: Fragment not attached to Activity
我尝试将代码放入 isAdded()
方法中以检查片段当前是否已添加到其 activity 中,但我仍然很少收到此错误。我不明白为什么我仍然收到此错误。我该如何预防?
在线显示错误-
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()
returns null.
- Volley
Response
表示为匿名内部 class,它隐含地持有对外部 Activity
class 的强引用。这会导致 classic 内存泄漏。
要解决这个问题,你应该总是这样做:
Activity activity = getActivity();
if(activity != null){
// etc ...
}
此外,在 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生命周期很复杂,bug多,尝试补充:
Activity activity = getActivity();
if (isAdded() && activity != null) {
...
}
如果您正在实例化无法实例化的片段,则会发生此错误:
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);
我找到了非常简单的解决方案 isAdded() 方法,它是识别当前片段是否附加到其 Activity 的片段方法之一。
我们可以在片段 class 的任何地方使用它,例如:
if(isAdded())
{
// using this method, we can do whatever we want which will prevent **java.lang.IllegalStateException: Fragment not attached to Activity** exception.
}
我可能会迟到但可能会帮助某人.....
最好的解决方案是创建一个全局应用程序 class 实例并在未附加 activity 的特定片段中调用它
如下图
icon = MyApplication.getInstance().getString(R.string.weather_thunder);
这是应用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;
}
}
当片段没有上下文时会发生这种情况,因此 getActivity() 方法 return 无效。
在获取上下文之前检查是否使用了它,或者 Activity 是否不再存在。在 fragment.onCreate 和 api 响应之后使用上下文通常会导致此问题
有时此异常是由支持库实现中的错误引起的。最近我不得不从 26.1.0 降级到 25.4.0 来摆脱它。
我采用了以下方法来处理这个问题。创建了一个新的 class 作为 activity 方法的包装器,例如
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
}
现在,无论我需要从片段或活动访问资源,而不是直接调用方法,我都使用这个 class。如果 activity context
不是 null
它 returns 资产的价值,如果 context
为空,它会传递一个默认值(也由函数的调用者指定。
重要 这不是解决方案,而是一种可以优雅地处理此崩溃的有效方法。如果您将 activity 实例设置为 null,您可能希望添加一些日志,并在可能的情况下尝试修复该问题。
异常: java.lang.IllegalStateException:片段
DeadlineListFragment{ad2ef970} 未附加到 Activity
类别:生命周期
说明: 在后台线程(如AsyncTask)进行耗时操作时,同时创建了一个新的Fragment,并被detach到Activity 在后台线程完成之前。 UI 线程中的代码(例如,onPostExecute)调用分离的片段,抛出此类异常。
修复方案:
暂停或停止时取消后台线程
片段
使用isAdded()检查片段是否被附加
然后从 activity.
到 getResources()
每当您调用不可用的上下文或调用它时为空的上下文时,就会出现此问题。当您在后台线程上调用主 activity 线程的上下文或在主 activity 线程上调用后台线程的上下文时,可能会出现这种情况。
例如,我更新了我的共享偏好字符串,如下所示。
editor.putString("penname",penNameEditeText.getText().toString());
editor.commit();
finish();
然后立即调用 finish()。现在它所做的是当提交在主线程上运行并停止任何其他异步提交,直到它完成。因此它的上下文在写入完成之前一直有效。因此之前的上下文是实时的,导致错误发生。
因此,如果某些代码存在此上下文问题,请务必重新检查您的代码。
在片段中使用isAdded()
如果片段当前附加到 Activity.
,它将 return 为真
如果你想在里面查看Activity
Fragment fragment = new MyFragment();
if(fragment.getActivity()!=null)
{ // your code here}
else{
//do something
}
希望对大家有所帮助
所以基本的想法是,你是 运行 一个 UI 操作 在进入 onDetach[ 的片段上=22=]生命周期。
当发生这种情况时,片段将离开堆栈并丢失 Activity.
的上下文
因此,当您调用 UI 相关函数时,例如调用进度微调器并且您想离开片段时,请检查片段是否已添加到堆栈中,如下所示:
if(isAdded){ progressBar.visibility=View.VISIBLE }
我在拨打 API 电话时很少遇到此错误。
java.lang.IllegalStateException: Fragment not attached to Activity
我尝试将代码放入 isAdded()
方法中以检查片段当前是否已添加到其 activity 中,但我仍然很少收到此错误。我不明白为什么我仍然收到此错误。我该如何预防?
在线显示错误-
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()
returns null. - Volley
Response
表示为匿名内部 class,它隐含地持有对外部Activity
class 的强引用。这会导致 classic 内存泄漏。
要解决这个问题,你应该总是这样做:
Activity activity = getActivity();
if(activity != null){
// etc ...
}
此外,在 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生命周期很复杂,bug多,尝试补充:
Activity activity = getActivity();
if (isAdded() && activity != null) {
...
}
如果您正在实例化无法实例化的片段,则会发生此错误:
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);
我找到了非常简单的解决方案 isAdded() 方法,它是识别当前片段是否附加到其 Activity 的片段方法之一。
我们可以在片段 class 的任何地方使用它,例如:
if(isAdded())
{
// using this method, we can do whatever we want which will prevent **java.lang.IllegalStateException: Fragment not attached to Activity** exception.
}
我可能会迟到但可能会帮助某人..... 最好的解决方案是创建一个全局应用程序 class 实例并在未附加 activity 的特定片段中调用它
如下图
icon = MyApplication.getInstance().getString(R.string.weather_thunder);
这是应用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;
}
}
当片段没有上下文时会发生这种情况,因此 getActivity() 方法 return 无效。 在获取上下文之前检查是否使用了它,或者 Activity 是否不再存在。在 fragment.onCreate 和 api 响应之后使用上下文通常会导致此问题
有时此异常是由支持库实现中的错误引起的。最近我不得不从 26.1.0 降级到 25.4.0 来摆脱它。
我采用了以下方法来处理这个问题。创建了一个新的 class 作为 activity 方法的包装器,例如
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
}
现在,无论我需要从片段或活动访问资源,而不是直接调用方法,我都使用这个 class。如果 activity context
不是 null
它 returns 资产的价值,如果 context
为空,它会传递一个默认值(也由函数的调用者指定。
重要 这不是解决方案,而是一种可以优雅地处理此崩溃的有效方法。如果您将 activity 实例设置为 null,您可能希望添加一些日志,并在可能的情况下尝试修复该问题。
异常: java.lang.IllegalStateException:片段
DeadlineListFragment{ad2ef970} 未附加到 Activity
类别:生命周期
说明: 在后台线程(如AsyncTask)进行耗时操作时,同时创建了一个新的Fragment,并被detach到Activity 在后台线程完成之前。 UI 线程中的代码(例如,onPostExecute)调用分离的片段,抛出此类异常。
修复方案:
暂停或停止时取消后台线程 片段
使用isAdded()检查片段是否被附加 然后从 activity.
到 getResources()
每当您调用不可用的上下文或调用它时为空的上下文时,就会出现此问题。当您在后台线程上调用主 activity 线程的上下文或在主 activity 线程上调用后台线程的上下文时,可能会出现这种情况。
例如,我更新了我的共享偏好字符串,如下所示。
editor.putString("penname",penNameEditeText.getText().toString());
editor.commit();
finish();
然后立即调用 finish()。现在它所做的是当提交在主线程上运行并停止任何其他异步提交,直到它完成。因此它的上下文在写入完成之前一直有效。因此之前的上下文是实时的,导致错误发生。
因此,如果某些代码存在此上下文问题,请务必重新检查您的代码。
在片段中使用isAdded()
如果片段当前附加到 Activity.
如果你想在里面查看Activity
Fragment fragment = new MyFragment();
if(fragment.getActivity()!=null)
{ // your code here}
else{
//do something
}
希望对大家有所帮助
所以基本的想法是,你是 运行 一个 UI 操作 在进入 onDetach[ 的片段上=22=]生命周期。
当发生这种情况时,片段将离开堆栈并丢失 Activity.
的上下文因此,当您调用 UI 相关函数时,例如调用进度微调器并且您想离开片段时,请检查片段是否已添加到堆栈中,如下所示:
if(isAdded){ progressBar.visibility=View.VISIBLE }