【问题标题】:Window leaked when using system overlay使用系统覆盖时窗口泄漏
【发布时间】:2015-03-17 19:01:15
【问题描述】:

当用户需要在应用程序范围内收到问题警报时,我正在使用系统覆盖来显示通知图标。当活动被破坏时,我得到一个泄漏的窗口,尽管我正在删除视图。

代码位于应用程序中大多数其他活动扩展的基本活动中。

protected void createOverlay(){
    if (overlayCreated) return;

    // Create System overlay video
    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.FILL_PARENT, 150,
            WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
            PixelFormat.TRANSLUCENT);
    params.gravity = Gravity.BOTTOM;

    LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    mOverlay = (LinearLayout) inflater.inflate(R.layout.overlay_notification, null);
    mOverlayImageView = (ImageView) mOverlay.findViewById(R.id.overlay_notification_image);

    WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    wm.addView(mOverlay, params);

    final Context context = this;

    mOverlay.setOnTouchListener(new View.OnTouchListener(){
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Toast.makeText(context, "WootHa!", Toast.LENGTH_SHORT).show();
            return true;
        }
    });
}

销毁

@Override
public void onDestroy() {
    super.onDestroy();

    // Remove view from WindowManager
    if (mOverlay != null) {
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        wm.removeView(mOverlay);

        mOverlay = null;
        mOverlayImageView = null;
    }
}

错误:

26576-26576/com.letstruck.mygauges E/WindowManager﹕ android.view.WindowLeaked: Activity com.letstruck.mygauges.ui.activity.fuel.TruckListActivity has leaked window android.widget.LinearLayout{431c4220 V.E..... ......I. 0,0-1080,150} that was originally added here
            at android.view.ViewRootImpl.<init>(ViewRootImpl.java:457)
            at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:267)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
            at com.letstruck.mygauges.ui.activity.LoggedInActivity.createOverlay(LoggedInActivity.java:125)
            at com.letstruck.mygauges.ui.activity.LoggedInActivity.onOptionsItemSelectedMain(LoggedInActivity.java:186)
            at com.letstruck.mygauges.ui.activity.fuel.TruckListActivity.onOptionsItemSelected(TruckListActivity.java:100)
            at android.app.Activity.onMenuItemSelected(Activity.java:2687)
            at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:373)
            at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:1103)
            at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:735)
            at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152)
            at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:874)
            at com.android.internal.view.menu.ListMenuPresenter.onItemClick(ListMenuPresenter.java:177)
            at android.widget.AdapterView.performItemClick(AdapterView.java:308)
            at android.widget.AbsListView.performItemClick(AbsListView.java:1483)
            at android.widget.AbsListView$PerformClick.run(AbsListView.java:3485)
            at android.widget.AbsListView$3.run(AbsListView.java:4843)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:157)
            at android.app.ActivityThread.main(ActivityThread.java:5356)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
            at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

  • onDestroy 不能保证被调用,你应该删除onPause中的窗口
  • 添加到 onPause(),仍然泄露。我已经对其进行了调试以验证是否正在调用代码。我的释放方法有问题吗?
  • 贴出完整代码
  • 这就是overlay的全部代码,需要的时候还会有其他代码调用createOverlay()方法。现在我只是把它绑定到一个菜单操作。

标签: android memory-leaks


【解决方案1】:

我有同样的问题。就我而言,我使用 wm.removeViewImmediate(View) 而不是 removeView(View) 解决了我的问题。也许你可以试试。

【讨论】:

  • PS:我做了一些进一步的测试,发现这个泄漏问题只发生在4.4以上的android版本上。 4.4之前,removeView()就可以了。
猜你喜欢
  • 2015-12-15
  • 1970-01-01
  • 2018-11-09
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
  • 2017-01-12
  • 1970-01-01
相关资源
最近更新 更多