2016-07-01 7 views
3

Я проверил исходный код Android и нашел следующий метод. (core/java/android/view/WindowManagerGlobal.java)Когда Android считает, что окно просочилось?

Кажется, что когда who != null просочилось окно/вид. Может ли кто-нибудь объяснить, что происходит за этим?

public void closeAll(IBinder token, String who, String what) { 
     synchronized (mLock) { 
      int count = mViews.size(); 
      //Log.i("foo", "Closing all windows of " + token); 
      for (int i = 0; i < count; i++) { 
       //Log.i("foo", "@ " + i + " token " + mParams[i].token 
       //  + " view " + mRoots[i].getView()); 
       if (token == null || mParams.get(i).token == token) { 
        ViewRootImpl root = mRoots.get(i); 

        //Log.i("foo", "Force closing " + root); 
        if (who != null) { 
         WindowLeaked leak = new WindowLeaked(
           what + " " + who + " has leaked window " 
           + root.getView() + " that was originally added here"); 
         leak.setStackTrace(root.getLocation().getStackTrace()); 
         Log.e(TAG, "", leak); 
        } 

        removeViewLocked(i, false); 
       } 
      } 
     } 
    } 

ответ

3

Я проверил источник ... Я не совсем уверен в этом, но она идет мое понимание ...

«который» аргумент активность Имя только

Поверка closeAll(), вы можете видеть, что who - это просто имя класса активности, которое было разрушено и оставлено на одно окно позади:

WindowManagerGlobal.getInstance().closeAll(wtoken, 
         r.activity.getClass().getName(), "Activity"); 

CloseAll() вызывается, если утечка произошла

Кажется, что WindowManagerGlobal.closeAll() вызывается, когда Windows, протекла уже. Итак, who != null это просто проверка, чтобы гарантировать, что String не NULL.

Если не null, то создается WindowLeaked и печатается журнал. WindowLeaked является класс, который расширяет AndroidRuntimeException

final class WindowLeaked extends AndroidRuntimeException { 
    public WindowLeaked(String msg) { 
     super(msg); 
    } 
} 

Наиболее важным является тот факт, что если WindowManagerGlobal.closeAll() называется, то это означает, что для Windows уже просочилась.

CloseAll() вызова метода

В View.java, мы можем видеть, что WindowManagerGlobal.closeAll() вызывается, когда leacked обнаружено:

ActivityThread.java

private void handleDestroyActivity(IBinder token, boolean finishing, 
            int configChanges, boolean getNonConfigInstance) { 
    ... 
    IBinder wtoken = v.getWindowToken(); 
    ... 
    if (wtoken != null && r.mPendingRemoveWindow == null) { 
     WindowManagerGlobal.getInstance().closeAll(wtoken, 
       r.activity.getClass().getName(), "Activity"); 
    } 

В коде выше, мы видим, что WindowManagerGlobal.closeAll() уволен при обнаружении несоответствия:

  1. wtoken != nullwtoken показывает, что View имеет mAttachInfo.mWindowToken информацию. Другими словами, он по-прежнему удерживается в каком-то окне.
  2. r.mPendingRemoveWindow == null Нет ожидаемого просмотра, чтобы удалить его.

Таким образом, это противоречиво. Один вид прикреплен (есть еще mAttachInfo), но я уже удаляю все ожидающие окна (mPendingRemoveWindow is null) ... Итак, этот вид просочился.

Надежда Я мог бы помочь вам Привет

REF:

WindowManagerGlobal

ActivityThread

View

+0

Великий ответ! Благодаря! Еще один вопрос: я заметил, что 'closeAll()' вызывается три раза (два раза в 'handleDestroyActivity' и один раз в' cleanUpPendingRemoveWindows', может ли утечка окна в других двух случаях? – JackWM

Смежные вопросы