ANR на некоторых устройствах при запуске активности
У меня ошибка на некоторых устройствах, которые иногда дают ANR при запуске нового действия. У меня небольшое запаздывание на моем устройстве (Samsung Galaxy S2), но я никогда не получаю ANR. Другие устройства, которые иногда получают ANR: HTC Desire HD и Xperia(о которых я знаю). Я думаю, что это может быть чем-то вроде интенсивной работы процессора, которая заставляет старые телефоны отставать больше, чем новые, но я не знаю. Я использую Asynctask, чтобы загрузить все тяжелые вещи, и поток пользовательского интерфейса на самом деле не делает много.
Вот код
Я создаю отдельную ветку для доступа к общим настройкам.
@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 - это 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));
}
Это Surfaceview, который рисует все и заботится о 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);
}
....
}
Я запускаю drawThread в 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();
}
}
Поверхность уничтожена путеводителем по сети
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...
}
}
}
Я думаю, что это важный код. Насколько я знаю, UIthread работает только через те части, которые я показал (возможно, не ondestroy, но я читал, что у кого-то была проблема с этим в другом потоке.). И это должно работать довольно быстро на большинстве систем.
Drawthread отображает только текст с надписью "загрузка", пока не выполнится asyncTask. Таким образом, когда все загружено и прорисовано, пользователь начинает касаться экрана, и тогда появляется ANR. Какие-нибудь советы?
Обновление (12-05-18): мне удалось получить logcat из эмулятора. Я использовал медленный компьютер, когда я использовал быстрый компьютер, ANR не показывался.
PID 860 - это активность
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
1 ответ
Это решено сейчас.
Мне удалось получить трассировку стека от этих устройств с помощью Google Play. Оказывается, в коде, который я разместил там, не было ничего плохого.
Я использовал код из учебника ( http://www.droidnova.com/playing-with-graphics-in-android-part-i,147.html). Этот код пытался получить surfaceHolder из drawThread каждый раз, когда происходило событие onTouchEvent.
Я предполагаю, что иногда drawThread находился внутри своего цикла и не мог освободить SurfaceHolder, когда UiTread пытался захватить его, что приводило к ANR.