我正在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
那么我需要做什么?提前致谢。
答案 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();
}
});
}
}
请告诉我这是否可以帮到你。