java - Android 运行 doInBackground 后 AsyncTask 未完成

标签 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

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

最佳答案

这件事的处理方式很奇怪。首先 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);
    }
}

然后像这样调用它(在上面的阅读下面部分中)

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

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

关于java - Android 运行 doInBackground 后 AsyncTask 未完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39961471/

相关文章:

java - 在打开文件之前如何知道编码方案?

java - Factual API 和 Coldfusion

java - 嵌套 JSON 映射到 Jackson,其中 key 是动态的

java - java - 如何声明数组而不必在java中给出固定的初始大小?

Android-从前置摄像头拍照会旋转照片

android - Fragment 中的 Asynctask 生命周期

java - Android:当两个字符串相等时,在 onPostExecute() 中启动一个新的 Activity

android - 如何将 GeoPoint 从 Firebase - Firestore 映射到 Android 中的 Kotlin DTO 对象

java - 简单的java代码行捕获了UnsupportedEncodingException,我不明白为什么

android - 我应该在 MainActivity 扩展 Activity 中使用 AsyncTask 类吗?