2013-01-07 9 views
9

Napisałem aplikację na Androida, która działa bezproblemowo na każdym telefonie, z którego próbowałem, z wyjątkiem Samsunga S3. Co się stanie, podczas gdy moja aplikacja będzie działać, inne procesy w tle (inne aplikacje) zaczną ginąć. Na przykład, po pewnym czasie korzystania z mojej aplikacji, Live Wallpaper umrze, a użytkownik dostanie czarne tło na swoim telefonie po wyjściu z mojej aplikacji. I wreszcie, po pewnym czasie korzystania z niej moja aplikacja jest również zabijana przez system operacyjny. Frustrujące jest to, że nie widzę w dzienniku żadnego komunikatu o błędzie, który dałby mi wskazówkę, na czym dokładnie polega problem.Procesy w tle losowo wymierające, gdy aplikacja działa na Samsung S3

Zdarza się to tylko na Samsung S3 (a nie na S2, na przykład).

Pomyślałem, że jest to związane z pamięcią, ponieważ moja aplikacja bardzo intensywnie korzysta z pamięci (ładuje wiele obrazów z internetu), ale nie widzę żadnych błędów "brak pamięci" w dzienniku.

Podejrzewałem również, że framework HTTP, którego używam, może być błędny, więc przełączyłem się z Apache HttpComponents na java.net.HttpURLConnection, ale to nie pomogło.

Każdy pomysł o tym, dlaczego tak się dzieje lub wskazówka, jak go usunąć, byłby doceniony.

Oto fragment z dziennika, który wykazuje pewne procesy w tle umierających (np Live Wallpaper):

01-07 01:57:37.245: I/InputDispatcher(2296): Delivering touch to current input target: action: 0x1 
01-07 01:57:37.505: D/dalvikvm(29490): GC_FOR_ALLOC freed 1535K, 17% free 28032K/33735K, paused 71ms, total 71ms 
01-07 01:57:37.580: D/dalvikvm(6718): WAIT_FOR_CONCURRENT_GC blocked 0ms 
01-07 01:57:37.620: D/dalvikvm(6718): GC_EXPLICIT freed 91K, 9% free 17663K/19399K, paused 3ms+5ms, total 40ms 
01-07 01:57:38.190: I/InputReader(2296): Touch event's action is 0x0 (deviceType=0) [pCnt=1, s=0.428 ] 
01-07 01:57:38.190: I/InputDispatcher(2296): Delivering touch to current input target: action: 0x0 
01-07 01:57:38.190: I/InputDispatcher(2296): Delivering touch to current input target: action: 0x0 
01-07 01:57:38.190: I/InputDispatcher(2296): Delivering touch to current input target: action: 0x0 
01-07 01:57:38.190: I/InputDispatcher(2296): Delivering touch to current input target: action: 0x0 
01-07 01:57:38.190: I/InputDispatcher(2296): Delivering touch to current input target: action: 0x0 
01-07 01:57:38.335: I/InputReader(2296): Touch event's action is 0x1 (deviceType=0) [pCnt=1, s=] 
01-07 01:57:38.335: I/InputDispatcher(2296): Delivering touch to current input target: action: 0x1 
01-07 01:57:38.335: I/InputDispatcher(2296): Delivering touch to current input target: action: 0x1 
01-07 01:57:38.335: I/InputDispatcher(2296): Delivering touch to current input target: action: 0x1 
01-07 01:57:38.750: D/dalvikvm(29490): GC_FOR_ALLOC freed 1688K, 18% free 27981K/33735K, paused 114ms, total 114ms 
01-07 01:57:39.695: W/PowerManagerService(2296): Timer 0x3->0x3|0x0 
01-07 01:57:39.700: D/PowerManagerService(2296): setTimeoutLocked::SmartSleep : after19500 
01-07 01:57:39.930: I/InputReader(2296): Touch event's action is 0x0 (deviceType=0) [pCnt=1, s=0.429 ] 
01-07 01:57:39.930: I/InputDispatcher(2296): Delivering touch to current input target: action: 0x0 
01-07 01:57:39.930: I/InputDispatcher(2296): Delivering touch to current input target: action: 0x0 
01-07 01:57:39.930: I/InputDispatcher(2296): Delivering touch to current input target: action: 0x0 
01-07 01:57:39.930: I/InputDispatcher(2296): Delivering touch to current input target: action: 0x0 
01-07 01:57:39.930: I/InputDispatcher(2296): Delivering touch to current input target: action: 0x0 
01-07 01:57:40.020: D/DeviceInfo(2296): SysScope Service has unexpectedly disconnected! 
01-07 01:57:40.065: I/InputReader(2296): Touch event's action is 0x1 (deviceType=0) [pCnt=1, s=] 
01-07 01:57:40.065: I/InputDispatcher(2296): Delivering touch to current input target: action: 0x1 
01-07 01:57:40.065: I/InputDispatcher(2296): Delivering touch to current input target: action: 0x1 
01-07 01:57:40.065: I/InputDispatcher(2296): Delivering touch to current input target: action: 0x1 
**01-07 01:57:40.080: I/ActivityManager(2296): Process com.android.smspush (pid 28031) (adj 1) has died.** 
01-07 01:57:40.090: W/WallpaperService(2296): Wallpaper service gone: ComponentInfo{com.sec.ccl.csp.app.secretwallpaper.themetwo/com.sec.ccl.csp.app.secretwallpaper.themetwo.SecretWallpaperService} 
01-07 01:57:40.125: D/KeyguardViewMediator(2296): setHidden false 
**01-07 01:57:40.135: I/ActivityManager(2296): Process com.android.server.device.enterprise:remote (pid 28016) (adj 1) has died.** 
**01-07 01:57:40.145: I/ActivityManager(2296): Process com.sec.ccl.csp.app.secretwallpaper.themetwo (pid 29715) (adj 1) has died.** 
01-07 01:57:40.285: D/dalvikvm(29490): GC_CONCURRENT freed 1616K, 17% free 28289K/33735K, paused 27ms+21ms, total 178ms 
01-07 01:57:40.285: D/dalvikvm(29490): WAIT_FOR_CONCURRENT_GC blocked 112ms 
01-07 01:57:40.445: D/dalvikvm(2296): GC_CONCURRENT freed 1869K, 59% free 24186K/57991K, paused 26ms+12ms, total 197ms 
01-07 01:57:40.660: D/dalvikvm(29490): GC_CONCURRENT freed 1587K, 16% free 28622K/33735K, paused 3ms+7ms, total 51ms 
01-07 01:57:40.685: D/KeyguardViewMediator(2296): setHidden false 
+1

Z Twojego opisu jest bardzo trudno wyśledzić taki błąd. Może być jednak związany z konkretnym S3. Czy możesz wypróbować to na innym telefonie S3? Mówię to, ponieważ jest bardzo dziwne, że inne aplikacje są zabijane przez Ciebie i po chwili twoja aplikacja zostanie zabita. Może jest coś, co zabija aplikacje ogólnie (wirus lub wadliwa pamięć?). Co więcej, tapety na żywo są zabijane przez cały czas przez Androida, ale są przywracane, gdy tylko zasoby zostaną uwolnione w twojej sytuacji, nie są więc możliwe, że coś uniemożliwia domyślne zachowanie systemu. – Christos

+0

Próbowałem na 3 różnych urządzeniach S3 (i one nie były nawet uruchomione w tej samej wersji Androida). Problem był w wycieku pamięci natywnej, zobacz moją odpowiedź. Naprawdę trudno było wyśledzić :( – kolufild

Odpowiedz

7

Wyśledziłem problem. W rzeczywistości był to wyciek pamięci spowodowany przez metodę Typeface.createFromAsset() opisaną jako here. Przeciekająca pamięć to pamięć rodzima (nie na stercie Java), dlatego nie było wyjątków OutOfMemory.

To, co jest dziwne, to kwestia ta powinna zostać naprawiona od czasu Honeycomb (3.0), ale w moim przypadku dzieje się to na S3, na którym działa JellyBean (4.1). (Próbowałem na kilku komputerach S3 i wszystkie mają ten problem). Byłoby interesujące, gdyby ktoś z dostępem do innego telefonu, który uruchamia JellyBean, przetestowałby, abyśmy mogli zobaczyć, czy się tam powiela (link, który zamieściłem pokazuje prosty sposób na jego odtworzenie).

9

Istnieją 3 główne powody, dla których proces w tle można zatykać i zacznę od mniej do najbardziej prawdopodobne:

Pytałeś inadvertedly poprosił go, aby zatrzymać

Sprawdź kod błędu, że w sytuacjach niewygodnych mógł zażądać, aby zatrzymać usługę. Może to być w ramach usługi lub w innej działalności z aplikacji.

Uncaught wyjątek

Usługa hit nieprzechwyconego wyjątek. W tej sytuacji powinieneś być w stanie zobaczyć informacje w dzienniku, jednak dziennik nie trwa długo i możesz go przegapić.

Aby zaradzić tej możliwości można ustawić DefaultUncaughtExceptionHandler takiego:

UncaughtExceptionHandler currentHandler = Thread.getDefaultUncaughtExceptionHandler(); 
if (!(currentHandler instanceof DefaultExceptionHandler)) { 
    // Register default exceptions handler 
    Thread.setDefaultUncaughtExceptionHandler(
      new DefaultExceptionHandler(currentHandler)); 
} 

i zdefiniować klasę DefaultExceptionHandler zapisu do pliku temp jak poniżej:

public class DefaultExceptionHandler implements UncaughtExceptionHandler { 
    private UncaughtExceptionHandler defaultExceptionHandler; 

    public DefaultExceptionHandler(UncaughtExceptionHandler pDefaultExceptionHandler) 
    { 
     defaultExceptionHandler = pDefaultExceptionHandler; 
    } 

    public void uncaughtException(Thread t, Throwable e) { 
     final Writer result = new StringWriter(); 
     final PrintWriter printWriter = new PrintWriter(result); 
     e.printStackTrace(printWriter); 
     try { 
      String filename = "your_temp_filename"; 
      BufferedWriter bw = new BufferedWriter(new FileWriter(filename)); 
      bw.write(result.toString()); 
     bw.flush(); 
     bw.close(); 
     } catch (Exception e2) { 
      e2.printStackTrace(); 
     } 
     defaultExceptionHandler.uncaughtException(t, e);   
    } 
} 

Android OS poprosił usługę zatrzymać

Na podstawie Twojego opisu jest to najbardziej prawdopodobne przyczyna, i ta, którą masz mniejszą kontrolę nad nią.

Nie ma sposobu, aby uniemożliwić Androidowi zabicie aplikacji, gdy potrzebuje ona dodatkowych zasobów lub gdy jej zdaniem usługa jest uruchomiona zbyt długo. Czas przeznaczony na uruchomienie usługi przed jej zabiciem może się zmienić z urządzenia na urządzenie, ponieważ zależy to od przydzielonych zasobów (np. Wielkość pamięci obrazów zmienia się wraz z rozmiarem ekranu) i dostępnych zasobów.

W tym przypadku jedyną rozsądną rzeczą, jaką możesz zrobić, to począwszy Ci usługi jako foreground service używając:

startForeground(int id, Notification notification); 

który informuje system operacyjny, że usługa została widoczność użytkownika i zostaną wprowadzone w tym mniej prawdopodobne, aby zabić lista usług. Moje doświadczenie z używaniem kilku urządzeń polega na tym, że usługa działa nieprzerwanie, nawet jeśli w międzyczasie używasz kilku innych aplikacji.

Pozdrawiam.

+0

Mój problem polega na tym, że INNE procesy zostały wyłączone podczas działania aplikacji MY. Na przykład możesz użyć mojej aplikacji przez jakiś czas, a po jej zakończeniu Live Wallpaper zniknie główny ekran telefonu, ponieważ jego proces jest zabijany (bez żadnego błędu pokazanego w dzienniku) – kolufild

+0

Nie rozumiem tego :-) Może powinieneś przeformułować nieco swoje pytanie. W każdym razie jesteś w sytuacji 3 opisanej powyżej, ale jako aplikacja, która prowadzi OS do zatrzymania innych usług tła w celu odzyskania pamięci. Czy wypróbowałeś "DDMS - Allocation Tracker" i/lub "MAT", aby sprawdzić, w jaki sposób twoja aplikacja korzysta z pamięci i znajduje potencjalne ulepszenia? – Luis

+0

Próbowałem tego. Wykorzystanie pamięci nigdy nie zbliża się do maksymalnego rozmiaru sterty. Ponadto ponowne uruchomienie odbywa się nawet w chwilach, gdy zużycie pamięci jest niskie. Wygląda na to, że mam opisany trzeci scenariusz, z tym że moja aplikacja nie jest usługą. Ale to frustrujące, że logi nie pokazują powodu, dla którego aplikacje są zabijane. – kolufild