如果处于调试模式,后台线程并不总是在Android onCreate()中工作

如果处于调试模式,后台线程并不总是在Android onCreate()中工作,android,Android,我需要在游戏活动的onCreate方法中执行一些初始处理。为了尝试在UI线程外执行该处理,我编写了以下内容: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... parentGrid = (ArrowGridLayout) findViewById(R.id.arrowPlainGrid); //populat

我需要在游戏活动的onCreate方法中执行一些初始处理。为了尝试在UI线程外执行该处理,我编写了以下内容:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    parentGrid = (ArrowGridLayout) findViewById(R.id.arrowPlainGrid);

    //populates the game board without blocking UI thread.
    new Thread(new Runnable() {
        @Override
        public void run() {
            final LevelFunction someLevel = new LevelFunction(parentGrid.getContext(), numRows, numCols, parentGrid, generateCardList(numRows, numCols), true);
            PlainArrowTest.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.i(TAG, "Look at me populating the level on a background thread!");
                    someLevel.populateGridCards();
                }
            });
        }
    }).start();
每次我在正常模式下使用Android Studio运行应用程序时,这似乎都能正常工作,但如果我在调试模式下运行它,活动将不会加载,因为它表示我正在或多或少地操作UI线程之外的UI对象。 我希望能够调试我的应用程序,而不必注释掉这段代码。你们有谁碰到过这个吗?有没有一种方法可以改变我的代码,以防止在调试中发生这种情况

以下是我的logcat输出:

05-23 00:21:52.792    2127-2127/bwg.arrow I/art﹕ Not late-enabling -Xcheck:jni (already on)
05-23 00:21:52.955    2127-2127/bwg.arrow W/ActivityThread﹕ Application bwg.arrow is waiting for the debugger on port 8100...
05-23 00:21:52.964    2127-2127/bwg.arrow I/System.out﹕ Sending WAIT chunk
05-23 00:21:52.975    2127-2134/bwg.arrow I/art﹕ Debugger is active
05-23 00:21:53.184    2127-2127/bwg.arrow I/System.out﹕ Debugger has connected
05-23 00:22:13.540    2127-2518/bwg.arrow I/GameLoop -﹕ Started run()...
05-23 00:22:13.541    2127-2518/bwg.arrow I/GameLoop -﹕ Nap time! Sleeping for 16 ms.
05-23 00:22:13.567    2127-2237/bwg.arrow W/EGL_emulation﹕ eglSurfaceAttrib not implemented
05-23 00:22:13.567    2127-2237/bwg.arrow W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa5d582a0, error=EGL_SUCCESS
05-23 00:22:13.670    2127-2518/bwg.arrow I/GameLoop -﹕ Nap time! Sleeping for 15 ms.
05-23 00:22:13.730    2127-2134/bwg.arrow W/art﹕ Suspending all threads took: 24.584ms
    --------- beginning of crash
05-23 00:22:13.734    2127-2517/bwg.arrow E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-120
    Process: bwg.arrow, PID: 2127
    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
            at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6247)
            at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:867)
            at android.view.View.requestLayout(View.java:17364)
            at android.view.View.requestLayout(View.java:17364)
            at android.view.View.requestLayout(View.java:17364)
            at android.view.View.requestLayout(View.java:17364)
            at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:360)
            at android.view.View.requestLayout(View.java:17364)
            at android.widget.GridLayout.requestLayout(GridLayout.java:1092)
            at android.widget.GridLayout.setRowCount(GridLayout.java:392)
            at bwg.arrow.LevelFunction.<init>(LevelFunction.java:54)
            at bwg.arrow.PlainArrowTest$1.run(PlainArrowTest.java:57)
            at java.lang.Thread.run(Thread.java:818)
05-23 00:22:13.841    2127-2139/bwg.arrow I/art﹕ Background sticky concurrent mark sweep GC freed 5497(318KB) AllocSpace objects, 0(0B) LOS objects, 36% free, 726KB/1135KB, paused 98.378ms total 194.327ms
05-23 00:22:13.890    2127-2518/bwg.arrow I/GameLoop -﹕ Nap time! Sleeping for 16 ms.
05-23 00:22:14.001    2127-2518/bwg.arrow I/GameLoop -﹕ Nap time! Sleeping for 16 ms.
05-23 00:22:14.065    2127-2518/bwg.arrow I/GameLoop -﹕ Nap time! Sleeping for 16 ms.
05-23 00:22:14.126    2127-2127/bwg.arrow I/PlainArrowTest﹕ Oh look at that! I paused the background thread. You're welcome.
05-23 00:22:15.711    2127-2127/bwg.arrow I/PlainArrowTest﹕ Oh look at that! I stopped the background thread. You're welcome.
05-23 00:22:15.711    2127-2127/bwg.arrow I/PlainArrowTest﹕ Oh look at that! I destroyed the background thread. You're welcome.
05-23 00:27:13.929    2127-2517/bwg.arrow I/Process﹕ Sending signal. PID: 2127 SIG: 9
        [...]
        at android.view.View.requestLayout(View.java:17364)
        at android.widget.GridLayout.setRowCount(GridLayout.java:392)
        at bwg.arrow.LevelFunction.<init>(LevelFunction.java:54)
        at bwg.arrow.PlainArrowTest$1.run(PlainArrowTest.java:57)
        at java.lang.Thread.run(Thread.java:818)

是的,您正在后台线程中操作UI对象,这是自找麻烦

查看您在logcat输出中获得的堆栈跟踪:

05-23 00:21:52.792    2127-2127/bwg.arrow I/art﹕ Not late-enabling -Xcheck:jni (already on)
05-23 00:21:52.955    2127-2127/bwg.arrow W/ActivityThread﹕ Application bwg.arrow is waiting for the debugger on port 8100...
05-23 00:21:52.964    2127-2127/bwg.arrow I/System.out﹕ Sending WAIT chunk
05-23 00:21:52.975    2127-2134/bwg.arrow I/art﹕ Debugger is active
05-23 00:21:53.184    2127-2127/bwg.arrow I/System.out﹕ Debugger has connected
05-23 00:22:13.540    2127-2518/bwg.arrow I/GameLoop -﹕ Started run()...
05-23 00:22:13.541    2127-2518/bwg.arrow I/GameLoop -﹕ Nap time! Sleeping for 16 ms.
05-23 00:22:13.567    2127-2237/bwg.arrow W/EGL_emulation﹕ eglSurfaceAttrib not implemented
05-23 00:22:13.567    2127-2237/bwg.arrow W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa5d582a0, error=EGL_SUCCESS
05-23 00:22:13.670    2127-2518/bwg.arrow I/GameLoop -﹕ Nap time! Sleeping for 15 ms.
05-23 00:22:13.730    2127-2134/bwg.arrow W/art﹕ Suspending all threads took: 24.584ms
    --------- beginning of crash
05-23 00:22:13.734    2127-2517/bwg.arrow E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-120
    Process: bwg.arrow, PID: 2127
    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
            at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6247)
            at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:867)
            at android.view.View.requestLayout(View.java:17364)
            at android.view.View.requestLayout(View.java:17364)
            at android.view.View.requestLayout(View.java:17364)
            at android.view.View.requestLayout(View.java:17364)
            at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:360)
            at android.view.View.requestLayout(View.java:17364)
            at android.widget.GridLayout.requestLayout(GridLayout.java:1092)
            at android.widget.GridLayout.setRowCount(GridLayout.java:392)
            at bwg.arrow.LevelFunction.<init>(LevelFunction.java:54)
            at bwg.arrow.PlainArrowTest$1.run(PlainArrowTest.java:57)
            at java.lang.Thread.run(Thread.java:818)
05-23 00:22:13.841    2127-2139/bwg.arrow I/art﹕ Background sticky concurrent mark sweep GC freed 5497(318KB) AllocSpace objects, 0(0B) LOS objects, 36% free, 726KB/1135KB, paused 98.378ms total 194.327ms
05-23 00:22:13.890    2127-2518/bwg.arrow I/GameLoop -﹕ Nap time! Sleeping for 16 ms.
05-23 00:22:14.001    2127-2518/bwg.arrow I/GameLoop -﹕ Nap time! Sleeping for 16 ms.
05-23 00:22:14.065    2127-2518/bwg.arrow I/GameLoop -﹕ Nap time! Sleeping for 16 ms.
05-23 00:22:14.126    2127-2127/bwg.arrow I/PlainArrowTest﹕ Oh look at that! I paused the background thread. You're welcome.
05-23 00:22:15.711    2127-2127/bwg.arrow I/PlainArrowTest﹕ Oh look at that! I stopped the background thread. You're welcome.
05-23 00:22:15.711    2127-2127/bwg.arrow I/PlainArrowTest﹕ Oh look at that! I destroyed the background thread. You're welcome.
05-23 00:27:13.929    2127-2517/bwg.arrow I/Process﹕ Sending signal. PID: 2127 SIG: 9
        [...]
        at android.view.View.requestLayout(View.java:17364)
        at android.widget.GridLayout.setRowCount(GridLayout.java:392)
        at bwg.arrow.LevelFunction.<init>(LevelFunction.java:54)
        at bwg.arrow.PlainArrowTest$1.run(PlainArrowTest.java:57)
        at java.lang.Thread.run(Thread.java:818)
这表示在后台线程上运行的LevelFunction调用GridLayout.setRowCount,然后尝试执行布局

你不能这样做。您应该在UI线程上运行所有操纵视图的代码。 这里的解决方案是删除Bojan Kseneman在评论中指出的附加线程

至于调试和发布正常版本之间的区别:调试是为了调试,除其他外,它意味着在程序中运行更多的健全性检查

线程的问题在所有类型的构建中都存在,但是调试构建能够尽早检测到它并抛出异常以让您知道问题所在