崩溃率排行榜第三,WindowManager$BadTokenException报错分析

本文详细分析了WindowManager中addView、removeView和removeViewImmediate方法的实现原理,探讨了在使用WindowManager时可能遇到的各种异常崩溃问题,特别是WindowManager$BadTokenException,通过源码分析提供了有效的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

640?wx_fmt=png


今日科技快讯


近日上海徐汇交警部门召集辖区快递、外卖企业负责人进行集中约谈,对前期发现积累的400余起“骑手”交通违法信息进行集中通报。美团、饿了么、必胜客宅急送、韵达、申通等企业区域负责人都到会,各负责人的座位前方有该企业骑手交通违法记录。其中美团、饿了么成“违法大户”。仅2018年12月6日至2019年1月5日,美团违法538起,饿了么违法699起。


作者简介


明天就是周六啦,提前祝大家周末愉快!

不知道大家还记不记得,几个月前我开直播讲Kotlin的时候提到了Android崩溃率排名前几的几个异常,其中第一是NullPointerException,第二是OutOfMemoryError,而第三就是WindowManager$BadTokenException了。

本篇来自 奔跑的平头哥 的投稿,和大家分享了WindowManager$BadTokenException这一错误的具体分析,希望对大家有所帮助!

奔跑的平头哥的博客地址:

https://www.jianshu.com/u/b4d21f49c053


简介


本文主要讲解WindowManager里的addView(View view, ViewGroup.LayoutParams params),removeView(View view),removeViewImmediate(View view)三个方法的实现原理,以及通过分析系统源码,解决我们在平常开发过程中使用WindowManager遇到的各种异常崩溃问题,本文因修改项目中的WindowManager$BadTokenException类型bug而来,所以以此命名。

源码版本

  • sdk:android-28

  • Android系统源码:Android8.0

功能

通过WindowManager实现一个悬浮在屏幕最上方的悬浮View,提示用户文件上传完成,以及点击查看文件内容。

//WindowManager实例获取:
mContext.getApplicationContext().getSystemService(Context.WINDOW_SERVICE)
//添加view
mWdm.addView(mToastView, mParams);
//移除View
mWdm.removeViewImmediate(mToastView);


场景1


在使用WindowManager时候,可能会遇到这样的异常:

View xxxxx@167788  has already been added to the window manager

看到这个异常,很多开发者立马能够想到是同一个View,在没有移除情况下,又执行了addView操作,于是,在添加之前判断该View是否已经有父容器了,有,者先移除该View:

final ViewParent parent = mToastView.getParent();
if (parent != null) {
     mWdm.removeView(mToastView);
}

改好,心想如此简单,脸上洋溢着开心的笑容,提交,打包,热更,完事,但是没想到,线上还是会报上面的异常。

于是,翻翻WindowManager里的Api,看到还有removeViewImmediate(View view)这个方法,通过文档,了解到这个方法与removeView(View view)不同在于前者是同步,后者是异步的,于是想到可能是removeView(View view)异步导致,执行添加之前View还没有来得及移除。

疑问

  1. removeView实现异步的方式是什么?

  2. 同步和异步表现的差异在哪里呢?

  3. 为什么在同步和异步移除的情况,得到View的父容器都是null,为什么用removeView会报异常呢?

带着疑问继续向向看吧!

于是采用同步移除的方式,测试几波,发现ok了,这下应该没事了吧,打包,热更,吃饭,哈哈哈哈哈!


场景2


突然第二天发现这个功能偶尔还是会出现崩溃,不同的是异常信息:

Unable to add window -- window android.view.ViewRootImpl$W@c84a531
 has already been added

眉头紧锁,着了,还是报什么View已经添加了,难道同步移除也不行,但是报的是ViewRootImpl已经添加了啊,这下完了,到底完没完,继续下看。

补充

也许发现,在不同的Android版本,手机,targetSdkVersion值,也会有不一样的现象,比如在targetSdkVersion指定在Android O及以上,当WindowManager.LayoutParams指定的类型为WindowManager.LayoutParams.TYPE_TOAST(官方已建议弃用),会直接崩溃,报以下错误:

Unable to add window -- token  null is not valid; is your activity running?

而在O以下却不会呢,这是为什么呢?带着疑问一起向下看吧!


开饭了


下面由我来进行逐一解疑:

removeView,removeViewImmediate异同

  • WindowManager.java实现类WindowManagerImpl.java

1. 分解操作:

mContext.getApplicationContext().getSystemService(Context.WINDOW_SERVICE)

//android.app.ContextImpl
@Override
public String getSystemServiceName(Class<?> serviceClass) {
    return SystemServiceRegistry.getSystemServiceName(serviceClass);
}

//android.app.SystemServiceRegistry
static{
    ...
    registerService(Context.WINDOW_SERVICE, WindowManager.class, new       
         CachedServiceFetcher<WindowManager>() {
            @Override
            public WindowManager createService(ContextImpl ctx) {
                return new WindowManagerImpl(ctx);
    }});
}

private static <T> void registerService(String serviceName, Class<T> serviceClass,ServiceFetcher<T> serviceFetcher) {
    SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
    SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}
  • removeView,removeViewImmediate

    //android.view.WindowManagerImpl
    @Override
    public void removeView(View view) {
        mGlobal.removeView(view, false);
    }

    @Override
    public void removeViewImmediate(View view) {
        mGlobal.removeView(view, true);
    }

关键就在这个boolean变量了(...省略的都是相同或者不重要的代码)

    //android.view.WindowManagerGlobal
    private void removeViewLocked(int index, boolean immediate) {
        ViewRootImpl root = mRoots.get(index);
         ...
        boolean deferred = root.die(immediate);
        if (view != null) {
            view.assignParent(null);
            if (deferred) {
                mDyingViews.add(view);
            }
        }
    }

关键点:

  1. view.assignParent(null);
    这个方法就是将View的父容器置null,通过该View的getParent()可以获取该父容
    器的对象。

  2. boolean deferred = root.die(immediate);

    //android.view.ViewRootImpl
    boolean die(boolean immediate) {
        if (immediate && !mIsInTraversal) {
            doDie();
            return false;
        }
        ...
        mHandler.sendEmptyMessage(MSG_DIE);
        return true;
    }

如果immediate为true立即调用doDie(),否则通过handler发送一个MSG_DIE消息,然后立即返回,这时候View并没有完成真正的删除操作,原来同步和异步是这么实现的

void doDie() {
    checkThread();
    if (LOCAL_LOGV) Log.v(mTag, "DIE in " + this + " of " + mSurface);
    synchronized (this) {
        if (mRemoved) {
            return;
        }
        mRemoved = true;
        if (mAdded) {
            dispatchDetachedFromWindow();
        }
        ...
        }
        mAdded = false;
    }
    WindowManagerGlobal.getInstance().doRemoveView(this);
}

dispatchDetachedFromWindow:

  1. 垃圾回收相关操作,比如清除数据和消息,移除回调。

  2. 通过Session的remove()删除Window,这同样是一个IPC过程,最终会调用WindowManagerService的removeWindow()。

  3. 调用View的dispatchDetachedFromWindow(),进而调用onDetachedFromWindow(),onDetachedFromWindowInternal()。onDetachedFromWindow()对于大家来说一定不陌生,我们可以在这个方法内部做一些资源回收工作,比如终止动画、停止线程等。
    最后再调用WindowManagerGlobal的doRemoveView()方法刷新数据,包括mRoots、mParams、mViews和mDyingViews,将当前Window所关联的对象从集合中删除。

  • 重要函数:dispatchDetachedFromWindow

void dispatchDetachedFromWindow() {
    ...
    mView.assignParent(null);
    mView = null;
    mAttachInfo.mRootView = null;
    ...
    try {
        mWindowSession.remove(mWindow);
    } catch (RemoteException e) {
    }
    ...
}
  • 移除window - mWindowSession.remove(mWindow);

mWindowSession.remove(mWindow);
--------------
@Override
public void remove(IWindow window) {
    mService.removeWindow(this, window);
}


//android.view.WindowManagerGlobal
public static IWindowSession getWindowSession() {
    ...
    InputMethodManager imm = InputMethodManager.getInstance();
    IWindowManager windowManager = getWindowManagerService();
    sWindowSession = windowManager.openSession(...);
    return sWindowSession;
    }
}
  • windowManager

IWindowManager windowManager = getWindowManagerService();
--------------
public static IWindowManager getWindowManagerService() {
    synchronized (WindowManagerGlobal.class) {
        if (sWindowManagerService == null) {
            sWindowManagerService = IWindowManager.Stub.asInterface(
                    ServiceManager.getService("window"));
          ...
        }
        return sWindowManagerService;
    }
}
  • ServiceManager.getService("window"))
    Android系统在启动时,会在SystemServer里面注册很多系统需要的服务,像AMS,PMS,WMS等

路径:framewor/base/setvices/java/com.android.server/SystemServer

private void startOtherServices() {

WindowManagerService wm = null;
...
wm = WindowManagerService.main(context, inputManager,mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL, !mFirstBoot, mOnlyCore, new PhoneWindowManager()); 
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
...
}
  • WindowManagerService.openSession

@Override
public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client,
        IInputContext inputContext)
 
{
    if (client == nullthrow new IllegalArgumentException("null client");
    if (inputContext == nullthrow new IllegalArgumentException("null inputContext");
    Session session = new Session(this, callback, client, inputContext);
    return session;
}
  • 关键代码:WindowManagerGlobal.getInstance().doRemoveView(this);

  1. mViews 存储的是所有Window对应的View

  2. mRoots 存储的是所有Window对应的ViewRootImpl

  3. mParams 存储的是所有Window对应的布局参数

  4. mDyingViews 待删除的View列表

请留意这个集合,一会说的异常就和这个相关

void doRemoveView(ViewRootImpl root) {
    synchronized (mLock) {
        final int index = mRoots.indexOf(root);
        //如果找到对应view的索引
        if (index >= 0) {
            mRoots.remove(index);
            mParams.remove(index);
            final View view = mViews.remove(index);
            mDyingViews.remove(view);
        }
    }
    if (ThreadedRenderer.sTrimForeground && ThreadedRenderer.isAvailable()) {
        doTrimForeground();
    }
}

addView(...)过程分析

1. 第一个异常:

throw new IllegalStateException("View " + view
         + " has already been added to the window manager.");

2. 抛出条件:
if (index >= 0 && ! mDyingViews.contains(view));

//android.view.WindowManagerGlobal
public void addView(View view, ViewGroup.LayoutParams params,
        Display display, Window parentWindow)
 
{
    ...
    ViewRootImpl root;
    View panelParentView = null;
    ...
        int index = findViewLocked(view, false);
        if (index >= 0) {
            if (mDyingViews.contains(view)) {
                // Don't wait for MSG_DIE to make it's way through root's queue.
                mRoots.get(index).doDie();
            } else {
                throw new IllegalStateException("View " + view
                        + " has already been added to the window manager.");
            }
            // The previous removeView() had not completed executing. Now it has.
        }
      ...
      //创建 new ViewRootImpl
        root = new ViewRootImpl(view.getContext(), display);
        view.setLayoutParams(wparams);
        mViews.add(view);
        mRoots.add(root);
        mParams.add(wparams);
        // do this last because it fires off messages to start doing things
        try {
            root.setView(view, wparams, panelParentView);
        } catch (RuntimeException e) {
            // BadTokenException or InvalidDisplayException, clean up.
            if (index >= 0) {
                removeViewLocked(index, true);
            }
            throw e;
        }
    }
}
  • 关键函数:ViewRootImpl - setView

//android.view.ViewRootImpl
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
    synchronized (this) {
       ...
            mAttachInfo.mRootView = view;
          ...
            mAdded = true;
            try {
             ...
                res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                        getHostVisibility(), mDisplay.getDisplayId(), mWinFrame,
                        mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                        mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel);
            } catch (RemoteException e) {
               ...
            } finally {
              ...
            }
        ...
        // 一大波异常来袭
            if (res < WindowManagerGlobal.ADD_OKAY) {
               ...
                switch (res) {
                    case WindowManagerGlobal.ADD_BAD_APP_TOKEN:
                    case WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN:
                        throw new WindowManager.BadTokenException(
                                "Unable to add window -- token " + attrs.token
                                + " is not valid; is your activity running?");
                    case WindowManagerGlobal.ADD_NOT_APP_TOKEN:
                        throw new WindowManager.BadTokenException(
                                "Unable to add window -- token " + attrs.token
                                + " is not for an application");
                    case WindowManagerGlobal.ADD_APP_EXITING:
                        throw new WindowManager.BadTokenException(
                                "Unable to add window -- app for token " + attrs.token
                                + " is exiting");
                    case WindowManagerGlobal.ADD_DUPLICATE_ADD:
                        throw new WindowManager.BadTokenException(
                                "Unable to add window -- window " + mWindow
                                + " has already been added");
                    case WindowManagerGlobal.ADD_STARTING_NOT_NEEDED:
                        // Silently ignore -- we would have just removed it
                        // right away, anyway.
                        return;
                    case WindowManagerGlobal.ADD_MULTIPLE_SINGLETON:
                        throw new WindowManager.BadTokenException("Unable to add window "
                                + mWindow + " -- another window of type "
                                + mWindowAttributes.type + " already exists");
                    case WindowManagerGlobal.ADD_PERMISSION_DENIED:
                        throw new WindowManager.BadTokenException("Unable to add window "
                                + mWindow + " -- permission denied for window type "
                                + mWindowAttributes.type);
                    case WindowManagerGlobal.ADD_INVALID_DISPLAY:
                        throw new WindowManager.InvalidDisplayException("Unable to add window "
                                + mWindow + " -- the specified display can not be found");
                    case WindowManagerGlobal.ADD_INVALID_TYPE:
                        throw new WindowManager.InvalidDisplayException("Unable to add window "
                                + mWindow + " -- the specified window type "
                                + mWindowAttributes.type + " is not valid");
                }
                throw new RuntimeException(
                        "Unable to add window -- unknown error code " + res);
            }
            ...
            //设置view的父容器
            view.assignParent(this);
          ...
        }
    }
}
  • 关键代码:

res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
      getHostVisibility(), mDisplay.getDisplayId(), mWinFrame,
      mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
      mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel);

//framewor/base/setvices/java/com.android.server/wm/Session

@Override
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
        int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets,
        Rect outOutsets, InputChannel outInputChannel)
 
{
    return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
            outContentInsets, outStableInsets, outOutsets, outInputChannel);
}

//framewor/base/setvices/java/com.android.server/wm/WindowManagerService

public int addWindow(Session session, IWindow client, int seq,
        WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
        Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
        InputChannel outInputChannel)
 
{
    int[] appOp = new int[1];
    //权限检测,有兴趣的可以自己点进去看看
    int res = mPolicy.checkAddPermission(attrs, appOp);
    if (res != WindowManagerGlobal.ADD_OKAY) {
        return res;
    }

    ...
    synchronized(mWindowMap) { 
    /** final WindowState win = new WindowState(this, session, client,    token, parentWindow,
         mWindowMap.put(client.asBinder(), win);
          win = mWindow = new W(this);
         public ViewRootImpl(Context context, Display display) {
            ...
            mWindow = new W(this);
            ...
         }

    */

      appOp[0], seq, attrs, viewVisibility, session.mUid,
      session.mCanAddInternalSystemWindow);

        //异常1
        if (mWindowMap.containsKey(client.asBinder())) {
            Slog.w(TAG_WM, "Window " + client + " is already added");
            return WindowManagerGlobal.ADD_DUPLICATE_ADD;
        }

        /**
          window类型type:
          type表示Window的类型,Window有三种类型,分别是应用Window,子
          Window和系统Window。

          应用类Window对应着一个Activity。子Window不能单独存在,它需要附属在特定的父Window中,比如Dialog就是一个子Window。系统Window
          是需要声明权限才能创建的Window,比如Toast和系统状态栏这些都是系统Window。

          Window是分层的,每个Window都有对应的z-ordered,层级大的会覆盖    在层级小的Window上。在三类Window中,应用Window的层级范围是1~99,子
          Window的层级范围是1000~1999,系统Window的层级范围是2000~2999。很显然系统Window的层级是最大的,而且系统层级有很多值,一
          般我们可以选用TYPE_SYSTEM_ERROR或者TYPE_SYSTEM_OVERLAY,另外重要的是要记得在清单文件中声明权限。

        */

        if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
            parentWindow = windowForClientLocked(null, attrs.token, false);
            if (parentWindow == null) {
                Slog.w(TAG_WM, "Attempted to add window with token that is not a window: "
                      + attrs.token + ".  Aborting.");
                return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
            }
            //子Window
            if (parentWindow.mAttrs.type >= FIRST_SUB_WINDOW
                    && parentWindow.mAttrs.type <= LAST_SUB_WINDOW) {
                Slog.w(TAG_WM, "Attempted to add window with token that is a sub-window: "
                        + attrs.token + ".  Aborting.");
                return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
            }
        }

        if (type == TYPE_PRIVATE_PRESENTATION && !displayContent.isPrivate()) {
            Slog.w(TAG_WM, "Attempted to add private presentation window to a non-private display.  Aborting.");
            return WindowManagerGlobal.ADD_PERMISSION_DENIED;
        }

       ...

        if (token == null) {
           //应用Window
            if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
                Slog.w(TAG_WM, "Attempted to add application window with unknown token "
                      + attrs.token + ".  Aborting.");
                return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
            }


            if (rootType == TYPE_WALLPAPER) {
                Slog.w(TAG_WM, "Attempted to add wallpaper window with unknown token "
                      + attrs.token + ".  Aborting.");
                return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
            }

           ....

            if (rootType == TYPE_ACCESSIBILITY_OVERLAY) {
                Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with unknown token "
                        + attrs.token + ".  Aborting.");
                return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
            }

            if (type == TYPE_TOAST) {
                // Apps targeting SDK above N MR1 cannot arbitrary add toast windows.
                if (doesAddToastWindowRequireToken(attrs.packageName, callingUid,
                        parentWindow)) {
                    Slog.w(TAG_WM, "Attempted to add a toast window with unknown token "
                            + attrs.token + ".  Aborting.");
                    return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                }
            }
         ...
        if (type == TYPE_TOAST) {
            if (!getDefaultDisplayContentLocked().canAddToastWindowForUid(callingUid)) {
                Slog.w(TAG_WM, "Adding more than one toast window for UID at a time.");
                return WindowManagerGlobal.ADD_DUPLICATE_ADD;
            }
            ...
        }

        // From now on, no exceptions or errors allowed!

        res = WindowManagerGlobal.ADD_OKAY;
        if (mCurrentFocus == null) {
            mWinAddedSinceNullFocus.add(win);
        }
        ...

        win.attach();
        mWindowMap.put(client.asBinder(), win);
       ...

        boolean imMayMove = true;

        win.mToken.addWindow(win);
        ...

    return res;
}
  • 异常分析:

if (type == TYPE_TOAST) {
    // Apps targeting SDK above N MR1 cannot arbitrary add toast windows.
    if (doesAddToastWindowRequireToken(attrs.packageName, callingUid,
            parentWindow)) {
        Slog.w(TAG_WM, "Attempted to add a toast window with unknown token "
                + attrs.token + ".  Aborting.");
        return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
    }
}

从注释// Apps targeting SDK above N MR1 cannot arbitrary add toast windows.可以看出,当targetSdkVersion大于N MR1,type == TYPE_TOAST 情况下是会直接崩溃的,报以下异常:

throw new WindowManager.BadTokenException(
       "Unable to add window -- token " + attrs.token
        + " is not valid; is your activity running?");
  • 异常分析:

if (type == TYPE_TOAST) {
    if (!getDefaultDisplayContentLocked().canAddToastWindowForUid(callingUid)) {
        Slog.w(TAG_WM, "Adding more than one toast window for UID at a time.");
        return WindowManagerGlobal.ADD_DUPLICATE_ADD;
    }
    ...
}

如果mParams的类型是TYPE_TOAST,对于同一个uid,在同一个时刻只能添加一个toast类型的Window,如果在上一个Window还没有移除时,又去添加新Window的操作,直接崩溃报以下异常:

Unable to add window -- window android.view.ViewRootImpl$W@c84a531 has already been added

但是不同Android系统版本,表现不一样,在我的Android5.1上测试,是可以同时添加多个Window,通过查看5.1系统源码,发现在5.1上没有上面的判断逻辑,具体从那个Android系统开始的,没有去查看。

里面还有很多异常,大家可以自己去查看。如果写得有不对的地方,欢迎留言。


640?wx_fmt=jpeg

分析以下代码的报错信息:------------------------- PROCESS STARTED (7432) for package com.example.myapplication ---------------------------- 2025-07-09 13:27:09.041 7432-7432 e.myapplicatio com.example.myapplication W ClassLoaderContext classpath size mismatch. expected=0, found=1 (PCL[] | PCL[/data/data/com.example.myapplication/code_cache/.overlay/base.apk/classes3.dex*4250602868]) 2025-07-09 13:27:09.042 7432-7432 e.myapplicatio com.example.myapplication W Found duplicate classes, falling back to extracting from APK : /data/app/~~dh0o8WK_fXecSV_JJz78RQ==/com.example.myapplication-RE5zX8NpQzXhviy1xPMobA==/base.apk 2025-07-09 13:27:09.042 7432-7432 e.myapplicatio com.example.myapplication W NOTE: This wastes RAM and hurts startup performance. 2025-07-09 13:27:09.042 7432-7432 e.myapplicatio com.example.myapplication W Found duplicated class when checking oat files: 'Lcom/example/myapplication/ListActivity$1;' in /data/data/com.example.myapplication/code_cache/.overlay/base.apk/classes3.dex and /data/app/~~dh0o8WK_fXecSV_JJz78RQ==/com.example.myapplication-RE5zX8NpQzXhviy1xPMobA==/base.apk!classes3.dex 2025-07-09 13:27:09.172 7432-7432 NetworkSecurityConfig com.example.myapplication D No Network Security Config specified, using platform default 2025-07-09 13:27:09.173 7432-7432 NetworkSecurityConfig com.example.myapplication D No Network Security Config specified, using platform default 2025-07-09 13:27:09.201 7432-7456 libEGL com.example.myapplication D loaded /vendor/lib/egl/libEGL_emulation.so 2025-07-09 13:27:09.202 7432-7456 libEGL com.example.myapplication D loaded /vendor/lib/egl/libGLESv1_CM_emulation.so 2025-07-09 13:27:09.204 7432-7456 libEGL com.example.myapplication D loaded /vendor/lib/egl/libGLESv2_emulation.so 2025-07-09 13:27:09.246 7432-7432 AppCompatDelegate com.example.myapplication D Checking for metadata for AppLocalesMetadataHolderService : Service not found 2025-07-09 13:27:09.305 7432-7432 e.myapplicatio com.example.myapplication W Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (greylist, reflection, allowed) 2025-07-09 13:27:09.305 7432-7432 e.myapplicatio com.example.myapplication W Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (greylist, reflection, allowed) 2025-07-09 13:27:09.397 7432-7454 HostConnection com.example.myapplication D HostConnection::get() New Host Connection established 0xe9a68250, tid 7454 2025-07-09 13:27:09.403 7432-7454 HostConnection com.example.myapplication D HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_vulkan ANDROID_EMU_deferred_vulkan_commands ANDROID_EMU_vulkan_null_optional_strings ANDROID_EMU_vulkan_create_resources_with_requirements ANDROID_EMU_YUV_Cache ANDROID_EMU_vulkan_ignored_handles ANDROID_EMU_has_shared_slots_host_memory_allocator ANDROID_EMU_vulkan_free_memory_sync ANDROID_EMU_vulkan_shader_float16_int8 ANDROID_EMU_vulkan_async_queue_submit ANDROID_EMU_sync_buffer_data ANDROID_EMU_vulkan_async_qsri ANDROID_EMU_read_color_buffer_dma GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_host_side_tracing ANDROID_EMU_gles_max_version_2 2025-07-09 13:27:09.404 7432-7454 OpenGLRenderer com.example.myapplication W Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without... 2025-07-09 13:27:09.411 7432-7454 EGL_emulation com.example.myapplication D eglCreateContext: 0xe9a68170: maj 2 min 0 rcv 2 2025-07-09 13:27:09.414 7432-7454 EGL_emulation com.example.myapplication D eglMakeCurrent: 0xe9a68170: ver 2 0 (tinfo 0xe9db64d0) (first time) 2025-07-09 13:27:09.438 7432-7454 Gralloc4 com.example.myapplication I mapper 4.x is not supported 2025-07-09 13:27:09.439 7432-7454 HostConnection com.example.myapplication D createUnique: call 2025-07-09 13:27:09.439 7432-7454 HostConnection com.example.myapplication D HostConnection::get() New Host Connection established 0xe9a6acc0, tid 7454 2025-07-09 13:27:09.467 7432-7454 HostConnection com.example.myapplication D HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_vulkan ANDROID_EMU_deferred_vulkan_commands ANDROID_EMU_vulkan_null_optional_strings ANDROID_EMU_vulkan_create_resources_with_requirements ANDROID_EMU_YUV_Cache ANDROID_EMU_vulkan_ignored_handles ANDROID_EMU_has_shared_slots_host_memory_allocator ANDROID_EMU_vulkan_free_memory_sync ANDROID_EMU_vulkan_shader_float16_int8 ANDROID_EMU_vulkan_async_queue_submit ANDROID_EMU_sync_buffer_data ANDROID_EMU_vulkan_async_qsri ANDROID_EMU_read_color_buffer_dma GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_host_side_tracing ANDROID_EMU_gles_max_version_2 2025-07-09 13:27:10.478 7432-7432 AndroidRuntime com.example.myapplication D Shutting down VM 2025-07-09 13:27:10.479 7432-7432 AndroidRuntime com.example.myapplication E FATAL EXCEPTION: main Process: com.example.myapplication, PID: 7432 android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running? at android.view.ViewRootImpl.setView(ViewRootImpl.java:1068) at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:409) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:109) at android.app.Dialog.show(Dialog.java:340) at android.app.AlertDialog$Builder.show(AlertDialog.java:1131) at com.example.myapplication.MyBaseAdapter$1.onClick(MyBaseAdapter.java:55) at android.view.View.performClick(View.java:7448) at android.view.View.performClickInternal(View.java:7425) at android.view.View.access$3600(View.java:810) at android.view.View$PerformClick.run(View.java:28305) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 2025-07-09 13:27:10.509 7432-7432 Process com.example.myapplication I Sending signal. PID: 7432 SIG: 9 ---------------------------- PROCESS ENDED (7432) for package com.example.myapplication ----------------------------
最新发布
07-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值