Im having a bug on some devices that sometimes give an ANR when starting a new activity. I have a small degree of lag on my device (Samsung Galaxy S2) but I never get an ANR. The other devices that sometimes gets an ANR is: HTC Desire HD and Xperia(That I know of). Im thinking that it could be somekind of cpu intensive thing I do that makes older phones lag more than newer ones, but I dont know. Im using an Asynctask to load all the heavy stuff and the ui thread doesnt really do much.
Heres the code
I create a separate thread here to access the shared preferences.
@Override
protected void onResume() {
super.onResume();
sound = false;
Thread prefThread = new Thread(new Runnable(){
public void run(){
SharedPreferences prefs = getSharedPreferences(SharedPrefValues.OPTION_PREF, Context.MODE_PRIVATE);
sound = prefs.getBoolean("sound", true);
String difficulty = prefs.getString(SharedPrefValues.DIFFICULTY, SharedPrefValues.DIF_MEDIUM);
prefs = getSharedPreferences(SharedPrefValues.HIGHSCORE_PREF, Context.MODE_PRIVATE);
for(int i = 0; i < mapPnl.buttons.size(); i++)
mapPnl.SetRank(mapPnl.buttons.get(i), prefs.getString(SharedPrefValues.HIGHSCORE_RANK_NAME + difficulty + mapPnl.buttons.get(i).getName(), SharedPrefValues.RANK_NOT_OK));
}
});
prefThread.start();
mapPnl.speedX = 0;
}
bgTask is an AsyncTask.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
Display display = getWindowManager().getDefaultDisplay();
screenSize = new Point();
screenSize.x = display.getWidth();
screenSize.y = display.getHeight();
mapPnl = new MapPnl(this);
LoadBitmapsStuff bgTask = new LoadBitmapsStuff(this);
bgTask.execute();
addContentView(mapPnl, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
}
This is the Surfaceview that draws everything and takes care of onTouchEvents
private class MapPnl extends SurfaceView implements SurfaceHolder.Callback{
...
public MapPnl(Context context) {
super(context);
getHolder().addCallback(this);
buttons = new ArrayList<ButtonMap>();
posX = 0;
speedX = 0;
maxX = 0;
drawThread = new DrawThread(getHolder());
drawThread.setRunning(true);
}
....
}
I start the drawThread in surfaceCreated
public void surfaceCreated(SurfaceHolder arg0) {
if(drawThread.getState() == Thread.State.NEW)
drawThread.start();
else if(drawThread.getState() == Thread.State.TERMINATED){
drawThread = new DrawThread(getHolder());
drawThread.setRunning(true);
drawThread.start();
}
}
Surfacedestroyed from guide on the web
public void surfaceDestroyed(SurfaceHolder arg0) {
boolean retry = true;
drawThread.setRunning(false);
while (retry) {
try {
drawThread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
I think that is the important code. As far as I know the UIthread only runs trough these parts Ive shown (maybe not the ondestroy but i read that someone had a problem with that one in another thread.). And that should run pretty fast on most systems.
The drawthread only displays a text that says "loading" until the asyncTask is done running. So when everything is loaded and drawn the user starts touching the screen and thats when the ANR comes up. Any tips?
Update (12-05-18): I managed to get a logcat from the emulator. I used a slow computor, when I used a fast computor the ANR didnt show up.
PID 860 is the activity
03-31 01:41:03.453: I/Process(71): Sending signal. PID: 860 SIG: 3
03-31 01:41:03.453: I/dalvikvm(860): threadid=3: reacting to signal 3
03-31 01:41:03.672: I/dalvikvm(860): Wrote stack traces to '/data/anr/traces.txt'
03-31 01:41:03.672: I/Process(71): Sending signal. PID: 71 SIG: 3
03-31 01:41:03.682: I/dalvikvm(71): threadid=3: reacting to signal 3
03-31 01:41:03.992: I/dalvikvm(71): Wrote stack traces to '/data/anr/traces.txt'
03-31 01:41:03.992: I/Process(71): Sending signal. PID: 381 SIG: 3
03-31 01:41:03.992: I/dalvikvm(381): threadid=3: reacting to signal 3
03-31 01:41:04.212: I/Process(71): Sending signal. PID: 349 SIG: 3
03-31 01:41:04.212: I/dalvikvm(349): threadid=3: reacting to signal 3
03-31 01:41:04.322: I/dalvikvm(349): Wrote stack traces to '/data/anr/traces.txt'
03-31 01:41:04.332: I/Process(71): Sending signal. PID: 664 SIG: 3
03-31 01:41:04.364: I/dalvikvm(664): threadid=3: reacting to signal 3
03-31 01:41:04.542: I/Process(71): Sending signal. PID: 364 SIG: 3
03-31 01:41:04.612: I/dalvikvm(364): threadid=3: reacting to signal 3
03-31 01:41:04.744: I/Process(71): Sending signal. PID: 371 SIG: 3
03-31 01:41:04.953: I/Process(71): Sending signal. PID: 822 SIG: 3
03-31 01:41:05.162: I/Process(71): Sending signal. PID: 139 SIG: 3
03-31 01:41:05.162: I/dalvikvm(139): threadid=3: reacting to signal 3
03-31 01:41:05.221: I/dalvikvm(822): threadid=3: reacting to signal 3
03-31 01:41:05.292: I/dalvikvm(371): threadid=3: reacting to signal 3
03-31 01:41:05.312: I/dalvikvm(139): Wrote stack traces to '/data/anr/traces.txt'
03-31 01:41:05.402: E/ActivityManager(71): ANR in se.blogspot.developingjsa.view (se.blogspot.developingjsa.view/.FirstMenu)
03-31 01:41:05.402: E/ActivityManager(71): Reason: keyDispatchingTimedOut
03-31 01:41:05.402: E/ActivityManager(71): Load: 1.79 / 1.63 / 1.31
03-31 01:41:05.402: E/ActivityManager(71): CPU usage from 5383ms to 64ms ago:
03-31 01:41:05.402: E/ActivityManager(71): elopingjsa.view: 51% = 49% user + 1% kernel / faults: 36 minor 7 major
03-31 01:41:05.402: E/ActivityManager(71): system_server: 44% = 41% user + 3% kernel / faults: 133 minor 1 major
03-31 01:41:05.402: E/ActivityManager(71): adbd: 1% = 0% user + 0% kernel
03-31 01:41:05.402: E/ActivityManager(71): m.android.phone: 1% = 0% user + 0% kernel / faults: 112 minor
03-31 01:41:05.402: E/ActivityManager(71): ronsoft.openwnn: 0% = 0% user + 0% kernel / faults: 22 minor
03-31 01:41:05.402: E/ActivityManager(71): com.svox.pico: 0% = 0% user + 0% kernel / faults: 7 minor
03-31 01:41:05.402: E/ActivityManager(71): logcat: 0% = 0% user + 0% kernel
03-31 01:41:05.402: E/ActivityManager(71): qemud: 0% = 0% user + 0% kernel
03-31 01:41:05.402: E/ActivityManager(71): id.defcontainer: 0% = 0% user + 0% kernel / faults: 6 minor
03-31 01:41:05.402: E/ActivityManager(71): ackageinstaller: 0% = 0% user + 0% kernel / faults: 5 minor
03-31 01:41:05.402: E/ActivityManager(71): TOTAL: 100% = 91% user + 8% kernel + 0% irq + 0% softirq