Android: AsyncTask, onPostExecute starts before do

2019-09-02 15:03发布

问题:

I had this problem a few hours ago (Android: AsyncTask, my 1st task has not finished when the other starts) I put it as solved but then I realized I had a similar problem.

Here is my main class "GameActivity"

              public void mainmethod()
                    Log.w("GAMEACTIVITY","actionup");
                    myAsyncRunnable mar = new myAsyncRunnable(GameActivity.this);
                    mar.execute("fire");

public void doPhotoTask() {
    PhotoTask photoTask = new PhotoTask(camera,surfaceCamera,isPreview,holder,GameActivity.this);
    photoTask.execute(null);
}

in myAsyncRunnable.fire() I have a loop that changes >10 times the image of an ImageView in gameActivity. I want the photoTask to start when the last image has been changed Here the code in myAsyncRunnable extends AsyncTask

@Override
protected Void doInBackground(String... params) {
fire();
return null;
}

public void fire() {
        final ImageView image3 = (ImageView) gameactivity.findViewById(R.id.imageView3);
        final int drawables[] = new int[] {R.drawable.fire1,R.drawable.fire2,R.drawable.fire3,R.drawable.fire4,R.drawable.fire5,R.drawable.fire6,R.drawable.fire7,R.drawable.fire8,R.drawable.fire9,R.drawable.fire10,R.drawable.fire11,R.drawable.fire12,R.drawable.fire13,R.drawable.fire14,R.drawable.fire15,R.drawable.fire16};
        for (int i=0;i<drawables.length;i++) {
            final int j=i;
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    image3.setImageResource(drawables[j]);
                     Log.w("GAMEACTIVITY","image"+j);
                }
            };
            gameactivity.handler.postDelayed(runnable, 200*j);
        }
    }

@Override
protected void  onPostExecute(Void result)  {
    Log.w("GAMEACTIVITY","ONPOSTEXECUTE");
    gameactivity.doPhotoTask();
}

in PhotoTask

@Override
    protected Void doInBackground(Boolean... params) {
         camera.takePicture(null,null, myPictureCallback_JPG);
            Log.w("GAMEACTIVITY","TAKEPICTURE");

            return null;
    }

My log cat

02-11 16:03:32.920: W/GAMEACTIVITY(7750): actionup
02-11 16:03:33.010: W/GAMEACTIVITY(7750): image0
02-11 16:03:33.010: W/GAMEACTIVITY(7750): ONPOSTEXECUTE
02-11 16:03:33.030: E/QualcommCameraHardware(99): takePicture(479)
02-11 16:03:33.100: E/QualcommCameraHardware(99): rawsize = 460800 cbcr offset =307200
02-11 16:03:33.110: E/QualcommCameraHardware(99): takePicture: X
02-11 16:03:33.110: W/GAMEACTIVITY(7750): TAKEPICTURE
02-11 16:03:33.120: E/mm-camera(99): camera_ops_start, CAMERA_OPS_CAPTURE_AND_ENCODE mode 1
02-11 16:03:33.350: W/GAMEACTIVITY(7750): image1
02-11 16:03:33.490: W/GAMEACTIVITY(7750): image2
02-11 16:03:33.780: W/GAMEACTIVITY(7750): image3
02-11 16:03:33.880: W/GAMEACTIVITY(7750): image4
02-11 16:03:34.110: W/GAMEACTIVITY(7750): image5
02-11 16:03:34.250: W/GAMEACTIVITY(7750): image6
02-11 16:03:34.490: W/GAMEACTIVITY(7750): image7
02-11 16:03:34.680: W/GAMEACTIVITY(7750): image8
02-11 16:03:34.880: W/GAMEACTIVITY(7750): image9
02-11 16:03:35.050: W/GAMEACTIVITY(7750): image10
02-11 16:03:35.110: E/QualcommCameraHardware(99): receiveRawPicture: E
02-11 16:03:35.280: W/GAMEACTIVITY(7750): image11
02-11 16:03:35.440: W/GAMEACTIVITY(7750): image12
02-11 16:03:35.500: E/QualcommCameraHardware(99): address of Jpeg 0 encoded buf 1085800448 Jpeg Heap base 1085800448
02-11 16:03:35.500: W/GAMEACTIVITY(7750): FIRST
02-11 16:03:36.470: W/GAMEACTIVITY(7750): INTENT
02-11 16:03:36.580: W/GAMEACTIVITY(7750): image13
02-11 16:03:36.710: W/GAMEACTIVITY(7750): image14
02-11 16:03:36.800: W/GAMEACTIVITY(7750): image15
02-11 16:03:37.320: W/GAMEACTIVITY(7750): SURFACEDESTROYED

回答1:

So the problem is you are timing future runnables for future execution, and then returning from the doInBackground - which immidiatly activates your onPostExecute function.

a solution to your problem is not to use the onPostExcute but instead to time another Runnable with the code you want to run after all the others, since they all run on the same thread this should solve your problem.



回答2:

Try this small change, it might help you.

Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    image3.setImageResource(drawables[j]);
                     Log.w("GAMEACTIVITY","image"+j);
            gameactivity.handler.postDelayed(this, 200*j);
                }
            };
          gameactivity.handler.postDelayed(runnable, 10);