Android 启动活动时某些设备上的ANR

Android 启动活动时某些设备上的ANR,android,android-intent,surfaceview,android-anr-dialog,Android,Android Intent,Surfaceview,Android Anr Dialog,我在一些设备上有一个bug,有时候在开始一个新的活动时会给出一个ANR。 我的设备(三星Galaxy S2)有一点滞后,但我从未得到过ANR。有时会得到ANR的其他设备是:HTC Desire HD和Xperia(据我所知)。 我在想,这可能是我做的某种cpu密集型的事情,使旧手机比新手机滞后,但我不知道。我用一个异步任务来加载所有繁重的东西,而ui线程实际上做不了什么 这是密码 我在这里创建一个单独的线程来访问共享首选项 @Override protected void onRes

我在一些设备上有一个bug,有时候在开始一个新的活动时会给出一个ANR。 我的设备(三星Galaxy S2)有一点滞后,但我从未得到过ANR。有时会得到ANR的其他设备是:HTC Desire HD和Xperia(据我所知)。 我在想,这可能是我做的某种cpu密集型的事情,使旧手机比新手机滞后,但我不知道。我用一个异步任务来加载所有繁重的东西,而ui线程实际上做不了什么

这是密码

我在这里创建一个单独的线程来访问共享首选项

  @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;
    }
这是一个表面视图,它可以绘制所有内容并处理所有事件

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);
        }
....
}
从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...
            }
        }

    }
我认为这是重要的代码。 据我所知,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
现在问题解决了

我使用谷歌play从这些设备上获得了堆栈跟踪。结果证明我贴在上面的代码没有任何问题

我在使用教程()中的代码。每次发生onTouchEvent时,该代码都试图从drawThread中获取surfaceHolder


我猜有时drawThread在其循环中,当UIRead试图抓住它时,无法释放surfaceHolder,从而导致ANR。

我无法在启用adb和logcat的情况下测试这些设备:/什么?您也有来自emulator的logcat…所以您的surfaceDestroyed方法正在阻塞,等待drawThread完成?至少有一个问题是UI线程由于任何原因都不允许阻止。@AndersMetnik:获取ANR的设备不是我的,所以我无法在它们上使用adb。虽然我没有想到要在模拟器上得到错误,但我还是用了一台速度较慢的计算机,得到了它的日志。我在原始帖子中发布了它。@LawrenceD'Oliveiro我认为只有在活动被销毁时才会调用surfaceedstroyed方法。在这种情况下,ANR将在创建活动时出现。恭喜修复!当你有能力时,请确保将你的答案标记为“已接受”(使用绿色复选标记),以便让其他人从你的成功中学习。干杯~谢谢:)我明天才能接受。到时候我会做的:)
    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...
            }
        }

    }
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