Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Background processes randomly dying while app is running on Samsung S3

I wrote an Android app which runs without problems on every phone I tried except Samsung S3. What happens is that, while my app is running, other background processes (other apps, that is) will start dying. For example, after some time of using my app, Live Wallpaper will die, and user will get a black background on his phone after exiting my app. And finally, after some time of using it, my app is also killed by OS. What's frustrating is that I cannot see any error message in log which would give me a hint as to what exactly is the problem.

This happens only on Samsung S3 (and not on S2, for example).

I thought it was memory related, since my app is very memory intensive (it is loading a lot of images from the web), but I can't see any "no memory" errors in log.

I also suspected that the HTTP framework I am using could be buggy, so I switched from Apache HttpComponents to java.net.HttpURLConnection, but it didn't help.

Any idea about why this is happening or a hint on how to debug it would be appreciated.

Here is an excerpt from the log which shows some background processes dying (for example, 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
like image 671
kolufild Avatar asked Jan 07 '13 01:01

kolufild


2 Answers

There are 3 main reasons why a background process may be stoped, and I'll start from the less to the most probable:

You asked inadvertedly asked it to stop

Check your code for a bug that in awkward situations could request the service to stop. This could be within the service or in other activity from your application.

Uncaught exception

The service hit an uncaught exception. In this situation you should be able to see the information in the log, however the log don't last for long and you may be missing it.

To address this possibility you can set a DefaultUncaughtExceptionHandler like this:

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

and define your DefaultExceptionHandler class to write to a temp file like this:

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 asked the service to stop

Based on your description this is the most probable cause, and the one that you have less control over it.

There is no way to prevent the Android from killing your application when it needs aditional resources or when it believes your service is running for too long. The time allowed for the service to run before being killed may change from device to device, as it depends on resources allocated (i.e. images memory requirement change with screen size) and resources available.

In this case, the only reasonable thing you can do is starting you service as foreground service using:

    startForeground(int id, Notification notification);

which informs the OS that your service has user visibility and will be put in the less probable to kill service's list. My experience using it with a few devices is that the service is kept running without interruption, even if you use several other applications in the mean time.

Regards.

like image 56
Luis Avatar answered Nov 06 '22 20:11

Luis


I have tracked down the issue. It was actually a memory leak caused by Typeface.createFromAsset() method as described here. The memory that was leaking is native memory (not on Java heap), so that's why there were no OutOfMemory exceptions.

What is odd is that this issue should be fixed since Honeycomb (3.0), but in my case, it is happening on S3 which is running JellyBean (4.1). (I tried on several S3s, and they all have this issue). It would be interesting if someone with access to a different phone that runs JellyBean would test, so we could see if it reproduces there (the link I posted shows a simple way to reproduce it).

like image 29
kolufild Avatar answered Nov 06 '22 20:11

kolufild