活动已泄露窗口 - Android

时间:2014-02-16 22:53:24

标签: java android cordova android-activity

看看这些代码:

Custom views and window attributes on Android

问题

当我点击“主页按钮”时,会抛出exceptionActivity已泄露窗口......来自此行:

localWindowManager.addView(colourView, layoutParams);

问题(S)

你知道是什么原因引起的吗?

当我使用后退按钮关闭应用程序时,问题不会发生。

异常/错误日志

W/InputManagerService(   96): Starting input on non-focused client com.android.internal.view.IInputMethodClient$Stub$Proxy@40908148 (uid=10056 pid=1368)
D/CordovaActivity( 1368): CordovaActivity.onDestroy()
D/CordovaWebView( 1368): >>> loadUrlNow()
E/WindowManager( 1368): Activity com.phonegap.helloworld.HelloWorld has leaked window pl.edu.uj.tcs.student.xxx.Display$Layer@40589368 that was originally added here
E/WindowManager( 1368): android.view.WindowLeaked: Activity com.phonegap.helloworld.HelloWorld has leaked window pl.edu.uj.tcs.student.xxx.Display$Layer@40589368 that was originally added here
E/WindowManager( 1368):         at android.view.ViewRoot.<init>(ViewRoot.java:258)
E/WindowManager( 1368):         at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
E/WindowManager( 1368):         at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
E/WindowManager( 1368):         at android.view.Window$LocalWindowManager.addView(Window.java:424)
E/WindowManager( 1368):         at pl.edu.uj.tcs.student.xxx.Display.setColorsViews(Display.java:181)
E/WindowManager( 1368):         at pl.edu.uj.tcs.student.xxx.Display$3.run(Display.java:139)
E/WindowManager( 1368):         at android.os.Handler.handleCallback(Handler.java:587)
E/WindowManager( 1368):         at android.os.Handler.dispatchMessage(Handler.java:92)
E/WindowManager( 1368):         at android.os.Looper.loop(Looper.java:130)
E/WindowManager( 1368):         at android.app.ActivityThread.main(ActivityThread.java:3683)
E/WindowManager( 1368):         at java.lang.reflect.Method.invokeNative(NativeMethod)
E/WindowManager( 1368):         at java.lang.reflect.Method.invoke(Method.java:507)
E/WindowManager( 1368):         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
E/WindowManager( 1368):         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
E/WindowManager( 1368):         at dalvik.system.NativeStart.main(Native Method)

D/CordovaActivity( 1368): onMessage(onPageStarted,about:blank)
D/CordovaWebViewClient( 1368): onPageFinished(about:blank)
D/CordovaActivity( 1368): onMessage(onPageFinished,about:blank)
D/CordovaActivity( 1368): onMessage(exit,null)
I/power   (   96): *** set_screen_state 0

修改

如何在 Cordova 活动中向onPause(),onStop()等函数添加内容?

编辑2:

为什么会出现问题?因为我创建的所有类都扩展了CordovaPlugin和小型辅助类。就这样。我无法(我想)修改Activity类体。我所能做的只是通过调用cordova.getActivity()函数来引用它。

5 个答案:

答案 0 :(得分:47)

编程有什么漏洞?

您获取但未释放的内存会导致内存泄漏。(窗口/对话框)也会发生类似情况。

这里发生了什么?

您正在尝试添加一个窗口,当它显示时它位于前台,但是当您按下主页按钮时它会暂停然后停止(尝试在onStop()和onPause()中放一个toast )。

由于您没有告诉系统删除​​您的视图,因此它仍然附加到现在已从应用程序中消失/分离的窗口。因此,根据系统,您的customView占用了它未释放的空间。

<强>解决方案

onStop() or onPause()onDestroy()内,请确保您关闭视图(dismiss()如果是对话框)或将其删除(如果使用窗口管理器添加remove())。< / p>

在你的卸载功能中添加解除或删除功能正如你所提到的,在按下后退按钮时你会收到此错误。退出应用程序时会调用其onUnload()方法。

建议(如果不在上下文中则忽略)

正如我可以观察到的那样,您正在尝试制作一个系统警报窗口,该窗口会覆盖其下方的任何内容。在活动中添加此类弹出窗口是有风险的,因为它可能会导致泄漏问题。 您实际上可以通过Service添加此类窗口,因此它比您的活动更长,并显示在设备上的任何位置(如果这是您需要的)。

Check this out

更新2-Cordova生命周期

为什么不尝试覆盖CordovaPlugin类中的onUnload方法。我尝试查找但docs提到了onPause和onResume方法的存在。如果在CordovaPlugin类中有onUnload,则删除视图你正在你的视图类runOnUiThread方法。

答案 1 :(得分:11)

您在退出活动后尝试显示Dialog

解决方案是在退出dismiss()之前致电您Dialog上的Activity,例如在onPause()中。在离开Activity之前,应关闭所有窗口和对话框。

@Override
 protected void onStop() {
  super.onStop();
  if (loadingDlg != null) {
   loadingDlg.dismiss();
   loadingDlg = null;
  }
}

希望它对你有所帮助。

Activity-has-leaked-window-that-was-originally-added

答案 2 :(得分:2)

检查对话框是否显示天气

@Override
  protected void onStop() {
    super.onStop();
if (loadingDlg != null) {

        if(loadingDlg.isShowing())
        loadingDlg.dismiss();

        loadingDlg = null;
 }
}

答案 3 :(得分:0)

泄露的窗口通常在您的上下文显示对话框时发生,并且突然强制关闭该上下文,因此您的对话框未被正确解除。

为了解决这个问题,你必须在窗口泄漏错误之前修复你的错误。

答案 4 :(得分:0)

我在调用AlertDialog之前调用了一个finish(),这导致Activity在调用AlertDialog之前完成。我删除了finish()并在用户使用AlertDialog完成输入后将其放置,并修复了窗口泄漏。