运行doInBackground Android后,AsyncTask无法完成

时间:2016-10-10 15:14:37

标签: java android android-asynctask android-camera

我正在TakePic课程上运行AsyncTask。在doInBackground函数中,我正在使用Camera.takePicture函数。现在一切都很好;我正在拍照并将文件保存到/sdcard/%d.jpg那个位置。

public class TakePic extends AsyncTask<CameraPreview, String, Integer> {

  @Override
  protected Integer doInBackground(final CameraPreview... params) {
          params[0].camera.takePicture(null,null,new Camera.PictureCallback() {
              @Override
              public void onPictureTaken(byte[] data, Camera camera) {
                  FileOutputStream outStream = null;
                  try {
                      outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
                      outStream.write(data);
                      outStream.close();
                      Log.e("picture_saved", "Picture has been saved succesfully: " + data.length);
                      camera.release();
                  } catch (FileNotFoundException e) {
                      e.printStackTrace();
                      Log.e("file_not_found: ","couldn't save the file "+e.getMessage());
                  } catch (IOException e) {
                      e.printStackTrace();
                      Log.e("IOexception: ","couldn't save the file "+e.getMessage());
                  }
              }
          });
      Log.e("doinback_compt:" ,"done");
      return 0;
  }

   @Override
   protected void onPostExecute(Integer integer) {
   }
}

但是在我的主类上执行这个AsyncTask之后它还没有完成。我需要执行另一个函数,我必须等到这个AsyncTask完成。所以在我执行AsyncTask后,我使用while循环来检查任务的状态,但状态永远不会改变。

    TakePic backCam=new TakePic();
    backCam.execute(cameraPreview_front);
    while (backCam.getStatus()!= AsyncTask.Status.FINISHED){
        *waiting for async task to finish*
    }

它停留在while循环中,我的logcat显示doInBackground运行正常,文件保存到该位置。

10-10 18:06:14.497 15975-15975/com.urun.camera_test E/clicked_capture:: ok
10-10 18:06:14.633 15975-16452/com.urun.camera_test E/doinback_compt:: done

那么我需要做什么?提前致谢。

4 个答案:

答案 0 :(得分:1)

这是以奇怪的方式处理的。第一个CameraPreview.camera.takePicture()将在后台运行,这就是你在构造函数中传递Camera.PictureCallback的原因。你只是在那里堆叠线程。在主线程中尝试这个

[yourCameraPreview].camera.takePicture(null,null,new Camera.PictureCallback() {
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        camera.release();
        // Read below
    }
}

现在我们可以等待图片回调。一旦我们获得数据,我们可以调用AsyncTask将其存储在文件中,并应用我们自己的回调来等待它的响应。我们可以利用静态内部类来完成所有工作。

private static class ImageSaver extends AsyncTask<Byte, Void, Exception>{

    public interface ImageSavedListener{
        void onImageSaved(Exception e);
    }

    private ImageSavedListener mCallback;

    public ImageSaver(ImageSavedListener callback){
        mCallback = callback;
    }

    @Override
    protected void doInBackground(Byte... data){
        if(data == null || data.length == 0)
            return new Exception("Data returned from camera is invalid");

        try {
            FileOutputStream outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
            outStream.write(data);
            outStream.close();
            Log.d("picture_saved", "Picture has been saved succesfully: " + data.length);
        } catch (FileNotFoundException e) {
            Log.e("file_not_found: ","couldn't save the file "+e.getMessage());
            return e;
        } catch (IOException e) {
            Log.e("IOexception: ","couldn't save the file "+e.getMessage());
            return e;
        }

        return null;
    }

    @Override
    protected void onPostExecute(Exception e){
        if(mCallback != null)
            mCallback.onImageSaved(e);
    }
}

然后像这样调用它(在上面Read below所述的部分中)

new ImageSaver(new ImageSavedListener(){
    @Override
    public void onImageSaved(Exception e){
        if(e == null){
            // do what you want
        }
        else
            e.printStackTrace();
    }
}).execute(data);

这将在后台拍摄照片,等待响应,在后台保存对文件的响应,等待响应,然后根据保存后返回的异常执行您想要的操作。

答案 1 :(得分:0)

如果您需要在Text执行后执行一些代码,我可以建议一个解决方案。 将您的AsyncTask代码包裹在*waiting for async task to finish*中并将其作为参数发送给异步任务(但这不是最佳解决方案,只需快速执行)

Runnable

您当前代码的可能问题是:

您没有执行 new AsyncTask<Object, Void, Runnable>() { @Override protected Runnable doInBackground(Object... runnables) { CameraPreview cp = (CameraPreview) runnables[0]; Runnable callback = (Runnable) runnables[1]; /**your main logic*/ return callback; } @Override protected void onPostExecute(Runnable aVoid) { super.onPostExecute(aVoid); if (aVoid != null) aVoid.run(); } }.execute( cameraPreview , new Runnable() { @Override public void run() { /**code to run();**/ } });

尝试将更改代码改为

super.onPostExecute(integer);

答案 2 :(得分:0)

如前所述,没有理由阻止你的主线程等待做某些事件。但是,如果您仍想从AsyncTask中获取某些内容,我建议您使用FutureTask

答案 3 :(得分:0)

正如我在代码中看到的那样,AsyncTask正在正确完成。 问题是你正在AsyncTask中拍照。因此,当Camera.PictureCallback正在等待图片时,任务在调用&#34; takePicture&#34;之后立即结束。方法

我应该做的是这样的事情(这只是一种方法):

  public class TakePic {

    public interface MyTakePicListener{
        void onPictureTaken();
        void onPictureError();
    }

    private MyTakePicListener myListener; 


    public void takePicture(CameraPreview cameraPreview) {
        cameraPreview.camera.takePicture(null, null, new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(final byte[] data, final Camera camera) {

                new Thread(new Runnable() {
                    @Override
                    public void run() {

                        FileOutputStream outStream = null;
                        try {
                            outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
                            outStream.write(data);
                            outStream.close();
                            Log.e("picture_saved", "Picture has been saved succesfully: " + data.length);
                            camera.release();

                            HERE you should call a listener to continue with your success code
                            myListener.onPictureTaken();
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                            Log.e("file_not_found: ", "couldn't save the file " + e.getMessage());

                            HERE you should call a listener to continue with your error code
                            myListener.onPictureError();
                        } catch (IOException e) {
                            e.printStackTrace();
                            Log.e("IOexception: ", "couldn't save the file " + e.getMessage());

                            HERE you should call a listener to continue with your error code
                            myListener.onPictureError();
                        }

                        Log.e("doinback_compt:", "done");



                    }
                }).start();
            }

        });
    }

}

请告诉我这是否可以帮到你。