2015-03-17 7 views
8

Moim celem jest utrzymanie aktywności dwóch UI i przełączanie się między nimi bez konieczności ich restartowania. Istnieje jednak poważny efekt uboczny, polegający na użyciu w tym celu funkcji: utrata fokusa okna po wznowieniu poprzedniej czynności (obecnie działającej w tle).Używanie FLAG_ACTIVITY_REORDER_TO_FRONT do przełączania się między stale działającymi funkcjami interfejsu użytkownika prowadzi do błędu "brak ostrości okna".

Udowodniłem ten problem, poświęcając 5 minut na stworzenie prostej aplikacji z dwoma działaniami "Hello World".

  1. Aplikacja rozpoczyna się od działania A, które po prostu pokazuje przycisk (nic więcej) o nazwie "Uruchom B".
  2. Naciśnij ten przycisk - spowoduje to aktywację czynności B, która po prostu pokazuje przycisk o nazwie "Uruchomienie A".
  3. Naciśnięcie tego przycisku - to wykonuje startActivity(FLAG_ACTIVITY_REORDER_TO_FRONT, ActivityA.class).
  4. działalności dla użytkownika onResume() nazywa się zgodnie z oczekiwaniami i wszystko wygląda w porządku (widzę aktywność zawartości ponownie).
  5. Prasa nastąpi klawisz Back urządzenia i ten zestaw błędów 100% czasu:

E/ActivityManager( 513): Reason: Input dispatching timed out (Waiting because no window has focus but there is a focused application that may eventually add a window when it finishes starting up.)

I/WindowState( 513): WIN DEATH: Window{5294687c u0 com.android.launcher/com.android.launcher2.Launcher}

W/ViewRootImpl(8066): Dropping event due to no window focus: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_BACK, scanCode=0, metaState=0, flags=0xc8, repeatCount=1, eventTime=14965546, downTime=14965045, deviceId=-1, source=0x101 }

(Praktycznym efektem okna śmierć jest w istocie „Crash” z punktu widzenia użytkownika - Android wyrzuca użytkownika z aplikacji z powrotem na ekran główny, ale pod względem technicznym aplikacja działa nadal w tle).

Po debugowaniu tego i stwierdziłem, że czynność A jest widoczna, ale nie ma ostrości, ponieważ działanie A na naWindowFocusChanged() NIE jest nazywane jak to ormally robi (nawet jeśli wywoływana jest onResume()). To ma coś wspólnego z faktem, że Aktywność B jest nadal aktywna w tle (nawet jeśli wyraźnie B stracił fokus - onWindowFocusChanged (false) został wywołany dla B, a także onStop()). Wiem o tym, ponieważ po kroku 4 powyżej, jeśli natychmiast zadzwonię do metody finish() na czynności B, funkcja A na onWindowFocusChanged (true) zostanie wywołana i wszystko będzie w porządku. Fakt, że Aktywność B jest nadal aktywna, ale nie jest skupiona, w jakiś sposób przeszkadza w Odzyskaniu Aktywności A tak jak powinien. Czy jest to błąd Androida, czy też coś mi brakuje?

Należy zauważyć, że jeśli działanie A ma wiele widoków i mam dotknąć jednego z tych widoków po kroku 6 powyżej, otrzymam takie samo zdarzenie "Upuszczenie zdarzenia z powodu braku ostrości okna", ale nie 100% czas z jakiegoś powodu.

+0

To błąd wprowadzony w Lollipop, zobacz: https://code.google.com/p/android/issues/detail? id = 91534 – xizzhu

+1

OK, faktycznie błąd został wprowadzony w 4.4.2: https://code.google.com/p/android/issues/detail?id=63570 – xizzhu

+1

Well- zadane pytanie z dobrymi pomysłami na temat przyczyny! Btw, jest to również śledzone w http://stackoverflow.com/questions/29804474 i http://stackoverflow.com/questions/31418683 –

Odpowiedz

1

Obejście przewidziane w https://code.google.com/p/android/issues/detail?id=63570#c15 pracował bardzo dobrze dla mnie, aby rozwiązać problem aktywności nie uzyskiwanie okna ostrości:

protected void onNewIntent(Intent intent) { 
    super.onNewIntent(intent); 
    if ((intent.getFlags() | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) > 0) { 
     if (android.os.Build.VERSION.SDK_INT >= 19 && !isTaskRoot()) { 
      ActivityManager tasksManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); 
      tasksManager.moveTaskToFront(getTaskId(), ActivityManager.MOVE_TASK_NO_USER_ACTION); 
     } 
    } 
} 

Będzie to również potrzeba zgody w AndroidManifest.xml

<uses-permission android:name="android.permission.REORDER_TASKS" /> 

I rzeczywiście uruchomić w tym wydaniu w Espresso test otrzymuje następujący błąd:

java.lang.RuntimeException: Waited for the root of the view hierarchy to have window focus and not be requesting layout for over 10 seconds. If you specified a non default root matcher, it may be picking a root that never takes focus. Otherwise, something is seriously wrong.

Powiązane problemy