简体   繁体   中英

Getting Updated UI in Android using Asynctask

I am building a Maze game in android (for a school assignment), and am having trouble getting an automated driver to work. The Game works fine for manual maze exploration, but when I try to use a driver to explore the maze the graphics don't update to the view. I know I have to use a handler somehow, but I am a bit lost on that matter. A few codeblocks below might help make things more clear.

This is in PlayActivity:

class RobotTask extends AsyncTask<Integer , Void , Void> {

    @Override
    protected Void doInBackground(Integer... params) {
        robotDriver.setView(mazeView);
        try {

            if(robotDriver.drive2Exit()) {
                Intent finishIntent = new Intent(PlayActivity.this, FinishActivity.class);
                startActivity(finishIntent);
            }
        } catch (Exception e) {
            Toast.makeText(PlayActivity.this, "Robot Ran Out Of Power", Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(PlayActivity.this , AMazeActivity.class);
            NavUtils.navigateUpTo(PlayActivity.this, intent);

        }
        return null;
    }

And then robotDriver.drive2Exit() calls a specific exploration algorithm which moves the robot, this code is below (not all of it, just where I assume I need a change):

if(forward)
            try {
                Thread.sleep(250);
                robot.move(1, true);
                this.mazeView.postInvalidate();
            } catch (HitObstacleException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();                        }
else {
            try {

                robot.rotate(90); // turn then move
                this.mazeView.postInvalidate();
                Thread.sleep(250);
                robot.move(1, true);
                this.mazeView.postInvalidate();
                Thread.sleep(500);
            } catch (HitObstacleException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    break;
                }
            }   

robot.move() and rotate() move the robot through the maze, and then update the two drawers classes I use to present the firstpersonview. These updates update the bitmap in mazeView, where I would hope that the postInvalidate() call would then feed these updates to the viewer.

Any thoughts would be helpful.

I don't think you can start the activity directly from the doInBackground() method and you can't update view from the worker thread. All these operations (Intent, Toast) have to be done in the UI thread

I think you problem is that you're trying to do some process that should update your UI thread on a thread that is not your UI thread. Either you want this process to run on your UI thread and update it accordingly, or you don't. According to the documentation postInvalidate() causes an invalidate to happen on a subsequent cycle through the event loop. So you should call invalidate() on the mazeview in your UI thread. To fix this you have to reorganize your code to something like the following. Make an async class to do your robot's moving caclulations:

    private final Robot robot;
public class RobotWorker extends AsyncTask<Void, Void, Void> {
    @Override
    protected Void doInBackground(Void... params) {
        //implement locking / synchronization here
        if( forward ) {//pas as a param
            try{
                Thread.sleep(250);
                robot.move(1,true);
            }catch( HitObstacleException e ){
                e.printStackTrace();
            }
        }
    else{
            try{
                robot.rotate(90);
                Thread.sleep(250);
            }catch( HitObstacleException e ){
                e.printStackTrace();
            }
        }
        return null;
    }
}

and on your UI thread do something like this

public void myRobotMover(){
    //implement locking / synchroniztion
    new RobotWorker().execute();
    mazeView.invalidate();
}

Again, you'll have to implement some synchronization and locking. Learn how to here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM