[英]AsyncTask doesn't finish after running doInBackground Android
我在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
其傳遞給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
的部分” Read below
)
new ImageSaver(new ImageSavedListener(){
@Override
public void onImageSaved(Exception e){
if(e == null){
// do what you want
}
else
e.printStackTrace();
}
}).execute(data);
這將在后台拍照,等待響應,將響應保存到后台的文件中,等待響應,然后根據保存后返回的異常執行所需的操作。
如果您需要在執行AsyncTask
之后執行一些代碼,我可以建議一種解決方案。 在Runnable
包裝*waiting for async task to finish*
代碼,並將其作為參數發送給Async任務(但這不是最好的解決方案,只是快速的解決方案)
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);
}
如前所述,阻塞您的主線程等待做某些事件是沒有意義的。 但是,如果您仍然想從AsyncTask中得到一些東西,我建議您使用FutureTask
正如我在您的代碼中看到的那樣,AsyncTask正在正確完成。 問題是您正在AsyncTask中拍照。 因此,當Camera.PictureCallback等待圖片時,在調用“ takePicture”方法后任務立即結束。
我應該做的是這樣的(這只是一種方法):
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();
}
});
}
}
請讓我知道這是否可以幫助您。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.