gpt4 book ai didi

android - Activity 泄漏了窗口/对话框(又是这个!)

转载 作者:可可西里 更新时间:2023-11-01 19:06:05 27 4
gpt4 key购买 nike

是的,我已经阅读了无数关于非常相同问题的问题。

我的代码很简单:我只是在 onCreate 上使用 showDialog(int id),然后旋转设备。 代码就是那个(测试用例),这足以引起问题。据我了解,showDialog 的方法会解决这个问题...对话框会消失,然后 onCreate 会在更改后稍后调用并显示对话框再次,干净利落。但不是。 这个推理有什么问题?

我(认为我)理解the cause ,但我不知道如何解决。即使是 iosched 应用程序在实现 EULA 窗口时也存在同样的问题(在 eula 对话框上更改方向,你会发现泄漏)。我读过有关在 onPause 时关闭对话框的信息,但是 1) 我冒着关闭尚未显示的风险,以及 2) 跟踪对话框似乎工作量太大。必须有更稳健的方法。

那么...处理该问题所需的更简洁的代码是什么?

谢谢。


记录错误输出:

01-30 00:27:18.615: E/WindowManager(20316): Activity com.test.PreSetupActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@418e0c28 that was originally added here
01-30 00:27:18.615: E/WindowManager(20316): android.view.WindowLeaked: Activity com.test.PreSetupActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@418e0c28 that was originally added here
01-30 00:27:18.615: E/WindowManager(20316): at android.view.ViewRootImpl.<init>(ViewRootImpl.java:343)
01-30 00:27:18.615: E/WindowManager(20316): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:245)
01-30 00:27:18.615: E/WindowManager(20316): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:193)
01-30 00:27:18.615: E/WindowManager(20316): at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:118)
01-30 00:27:18.615: E/WindowManager(20316): at android.view.Window$LocalWindowManager.addView(Window.java:537)
01-30 00:27:18.615: E/WindowManager(20316): at android.app.Dialog.show(Dialog.java:274)
01-30 00:27:18.615: E/WindowManager(20316): at com.test.PreSetupActivity.onCreate(PreSetupActivity.java:88)
01-30 00:27:18.615: E/WindowManager(20316): at android.app.Activity.performCreate(Activity.java:4465)
01-30 00:27:18.615: E/WindowManager(20316): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
01-30 00:27:18.615: E/WindowManager(20316): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1919)
01-30 00:27:18.615: E/WindowManager(20316): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1980)
01-30 00:27:18.615: E/WindowManager(20316): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3347)
01-30 00:27:18.615: E/WindowManager(20316): at android.app.ActivityThread.access$700(ActivityThread.java:122)
01-30 00:27:18.615: E/WindowManager(20316): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1150)
01-30 00:27:18.615: E/WindowManager(20316): at android.os.Handler.dispatchMessage(Handler.java:99)
01-30 00:27:18.615: E/WindowManager(20316): at android.os.Looper.loop(Looper.java:137)
01-30 00:27:18.615: E/WindowManager(20316): at android.app.ActivityThread.main(ActivityThread.java:4340)
01-30 00:27:18.615: E/WindowManager(20316): at java.lang.reflect.Method.invokeNative(Native Method)
01-30 00:27:18.615: E/WindowManager(20316): at java.lang.reflect.Method.invoke(Method.java:511)
01-30 00:27:18.615: E/WindowManager(20316): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
01-30 00:27:18.615: E/WindowManager(20316): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
01-30 00:27:18.615: E/WindowManager(20316): at dalvik.system.NativeStart.main(Native Method)

最佳答案

有一个内部类充当您的状态持有者,并在其中有一个 bool 字段,指示您的对话框是否正在显示。使用 onRetainNonConfigurationInstance 跟踪方向变化,并在 onResume

上重新显示对话框

这里是一些代码+伪代码:

public class ProfileActivity extends Activity {
private StateHolder mStateHolder;
private Dialog dialog;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Object retained = getLastNonConfigurationInstance();
if (retained != null && retained instanceof StateHolder) {
mStateHolder = (StateHolder) retained;
} else {
mStateHolder = new StateHolder();
}
}

@Override
public Object onRetainNonConfigurationInstance() {
return mStateHolder;
}

@Override
public void onPause() {
super.onPause();
if(dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
}

@Override
public void onResume() {
if(mStateHolder.mIsShowingDialog) {
dialog.show();
}
}

private void showDialog() {
mStateHolder.mIsShowingDialog = true;
dialog.show();
}

private static class StateHolder {
boolean mIsShowingDialog;
public StateHolder() {}
}

}

关于android - Activity 泄漏了窗口/对话框(又是这个!),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9059116/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com