我在我的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
那么我需要做什么呢?提前谢谢。
发布于 2016-10-10 23:59:53
这是以一种奇怪的方式处理的。首先,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);
这将在后台拍摄图片,等待响应,将响应保存到后台的文件中,等待响应,然后根据保存后返回的异常执行所需的操作。
发布于 2016-10-10 23:27:27
如果您需要在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);
尝试将代码更改为
@Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
}
发布于 2016-10-10 23:48:13
正如前面指出的,阻塞你的主线程等待做某些事件是没有意义的。然而,如果你仍然想从你的AsyncTask中得到一些东西,我建议你使用FutureTask
https://stackoverflow.com/questions/39961471
复制相似问题