【问题标题】:Android thread intermittently stops?Android线程间歇性停止?
【发布时间】:2012-03-26 12:17:59
【问题描述】:

我正在为 Android 编写游戏。一种游戏风格是让用户与机器对战。在游戏的每次迭代中,用户或机器都会在棋盘上放置满足游戏规则的棋子。轮到机器时,我在放置瓷砖时使用简单的首次拟合算法。我遍历可用的图块,遍历板的行和列,然后循环遍历每个图块的一系列 3 次旋转,直到找到一个位置。这可能是一个冗长的操作,所以我使用线程来完成这项工作。大约三分之二的时间,它可以完美运行。但是,有时它会间歇性地停止搜索 在没有错误消息的一两个瓷砖之后。由于我在搜索之前将 'found' 标志设置为 false,因此线程返回为没有找到任何东西,它就这样继续下去。但是,如果瓷砖继续通过而不会被打断,则有可用的位置放置瓷砖。

下面是我启动线程和搜索循环的代码。

-有人在代码中看到任何可疑之处吗? - 我能做些什么来追踪为什么线程在完成之前和找到一个点之前停止循环?我可以看到 Log.d 喷出列/行和旋转以及每个图块的顶点,然后它就退出了,有时只在一两列之后,有时它会一直遍历数据。

启动线程并等待结果

private void playDeviceTile() {

    if (mDbHelper.isPlayingDevice(game_id)) {

        // make sure I'm seeing all played tiles
        refreshPlayedTiles();

        final Boolean found;



        final ProgressDialog dialog = new ProgressDialog(mcontext);
        dialog.setMessage("Android is thinking...");  
        dialog.show();

            new AsyncTask<Void,Void, Boolean>(){
                @Override
                protected void onPostExecute(Boolean isFound) {
                    if (!isFound) {

                            passPlay(1);  // never found a tile to play. We have to pass
                        }
                        else {
                    playTile(currentTile,1);   

                    }
                    dialog.dismiss();
                    postInvalidate();
                    invalidate();
                }

                @Override
                protected Boolean doInBackground(Void... params) {
                    try {
                        return doSearchforSpot();
                    } catch (Exception e) {
                        Log.e("DRAW", "Exception find spot for device tile", e);
                    }
                    return null;
                }

            }.execute();

    }
}

进行实际搜索

private Boolean doSearchforSpot(){
    Boolean found = false;
    tileClass tile;
    int tileNum;
    BoardClass spot;
    int rot;
    int maxrot;
    int score = -1;
    int i = 0;

    // totally brain-less, brute-force, 1st fit.  Loop through
    // all open spots on the board, and check each tile in each rotation
    // and return the first time a valid placement and score occurs. 

    while ((i < deviceHandNumber) && (!found)) {
        tileNum = deviceHand[i];
        tile = tiles.get(tileNum);
        int row = TileExtents[TOP];
        int col = TileExtents[LEFT];
        while ((row <= TileExtents[BOTTOM]) && (!found)) {
            while ((col <= TileExtents[RIGHT]) && (!found)) {

                spot = board.get(ColRowGrid[col][row]);
                if (!spot.occupied) {
                    if (spot.facedown) {
                        rot = 3;
                        maxrot = 6;
                    }
                    else {
                        rot = 0;
                        maxrot = 3;
                    }
                    while ((rot < maxrot) && (!found)) {
                        // set the rotation and check for a score
                        tile.setRotate(rot);
                        Log.d("WTF","CRT "+col+" "+row+" "+rot+" "+tile.getScore(0)+" "+tile.getScore(1)+" "+tile.getScore(2));
                        score = placeTileOnBoard(spot.index, tileNum);

                        if (score >= 0) {
                            // hey! we found a spot. Play it.
                            turnScore = score;
                            currentTile = tileNum;
                            found = true;
                        }
                        rot++;
                    }

                }
                col++;

            }
            row++;
            col=TileExtents[LEFT];
        }
        i++;

    }
    return found;

}

【问题讨论】:

  • 你得到答案了吗?如果是,请发布它以帮助面临同样问题的其他人。

标签: android


【解决方案1】:

我不久前解决了这个问题。尽管人们有意见,但与使用异步或线程无关。这只是我的多线程代码覆盖变量的情况。我的代码的另一部分检查边界 - 首先将它们归零。我的搜索代码正在使用这些边界。我只是没有意识到他们在搜索过程中得到了更新,这很难找到。

【讨论】:

    【解决方案2】:

    尝试直接使用线程而不是 AsyncTask。 它应该工作。

    【讨论】:

    • 那么我如何同步输出,以便用结果填充 UI?我使用 AsyncTask 是因为它有那个可爱的小 postExecute
    • 到目前为止没有答案....Javanator,除非您有一些数据来支持您的声明,即执行 Thread vs AsyncTask 会起作用,您的答案是错误的。它们都只是在线程中工作。
    • stackoverflow.com/questions/4080808/… 我也遇到了同样的情况,之后不相信 AysncTask 的表现。我终于编写了自己的基于传统线程的任务框架。并制作了我自己的 onPreExecute 和 onPostExecute 来执行 runOnUIThread() 。 java可以使它们同步工作。在很多方面。
    猜你喜欢
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多