.NET을 사용하여 백그라운드 스레드에서 원격 오디오 파일 가져 오기 및 오디오 파일 재생 작업을 실행하고 AsyncTask
있습니다. Cancellable
진행 표시 줄은 동작의 실행을 인출 시간이 표시됩니다.
AsyncTask
사용자가 작업을 취소 (반대 결정)하면 실행 을 취소 / 중단하고 싶습니다 . 그러한 사건을 처리하는 이상적인 방법은 무엇입니까?
답변
그냥 발견 AlertDialogs
의 boolean cancel(...);
나는 모든 곳에서 실제로 사용 아무것도 안 했어요. 큰.
그래서…
public class MyTask extends AsyncTask<Void, Void, Void> {
private volatile boolean running = true;
private final ProgressDialog progressDialog;
public MyTask(Context ctx) {
progressDialog = gimmeOne(ctx);
progressDialog.setCancelable(true);
progressDialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
// actually could set running = false; right here, but I'll
// stick to contract.
cancel(true);
}
});
}
@Override
protected void onPreExecute() {
progressDialog.show();
}
@Override
protected void onCancelled() {
running = false;
}
@Override
protected Void doInBackground(Void... params) {
while (running) {
// does the hard work
}
return null;
}
// ...
}
답변
계산을하는 경우 :
isCancelled()
주기적으로 확인 해야합니다.
HTTP 요청을하는 경우 :
- 자신
HttpGet
또는HttpPost
다른 곳에 (예 : 공개 필드) 인스턴스를 저장합니다 . - 호출 한 후
cancel
, 호출request.abort()
. 이것은IOException
당신의doInBackground
.
제 경우에는 다양한 AsyncTasks에서 사용한 커넥터 클래스가있었습니다. 간단하게 abortAllRequests
하기 위해 해당 클래스에 새 메서드를 추가 하고을 호출 한 직후이 메서드를 호출했습니다 cancel
.
답변
문제는 AsyncTask.cancel () 호출이 작업에서 onCancel 함수 만 호출한다는 것입니다. 여기에서 취소 요청을 처리 할 수 있습니다.
다음은 업데이트 메서드를 트리거하는 데 사용하는 작은 작업입니다.
private class UpdateTask extends AsyncTask<Void, Void, Void> {
private boolean running = true;
@Override
protected void onCancelled() {
running = false;
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
onUpdate();
}
@Override
protected Void doInBackground(Void... params) {
while(running) {
publishProgress();
}
return null;
}
}
답변
간단합니다 AsyncTask
.. AsyncTask
빠르게 (수십 초) 종료되는 짧은 작업을 위해 설계되었으므로 취소 할 필요가 없습니다. “오디오 파일 재생”은 적합하지 않습니다. 일반 오디오 파일 재생을위한 백그라운드 스레드도 필요하지 않습니다.
답변
이를 수행하는 유일한 방법은 isCancelled () 메서드의 값을 확인하고 true를 반환하면 재생을 중지하는 것입니다.
답변
이것이 제가 AsyncTask를 작성하는 방법입니다
. 핵심은 add Thread.sleep (1);
@Override protected Integer doInBackground(String... params) {
Log.d(TAG, PRE + "url:" + params[0]);
Log.d(TAG, PRE + "file name:" + params[1]);
downloadPath = params[1];
int returnCode = SUCCESS;
FileOutputStream fos = null;
try {
URL url = new URL(params[0]);
File file = new File(params[1]);
fos = new FileOutputStream(file);
long startTime = System.currentTimeMillis();
URLConnection ucon = url.openConnection();
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
byte[] data = new byte[10240];
int nFinishSize = 0;
while( bis.read(data, 0, 10240) != -1){
fos.write(data, 0, 10240);
nFinishSize += 10240;
**Thread.sleep( 1 ); // this make cancel method work**
this.publishProgress(nFinishSize);
}
data = null;
Log.d(TAG, "download ready in"
+ ((System.currentTimeMillis() - startTime) / 1000)
+ " sec");
} catch (IOException e) {
Log.d(TAG, PRE + "Error: " + e);
returnCode = FAIL;
} catch (Exception e){
e.printStackTrace();
} finally{
try {
if(fos != null)
fos.close();
} catch (IOException e) {
Log.d(TAG, PRE + "Error: " + e);
e.printStackTrace();
}
}
return returnCode;
}
답변
글로벌 AsyncTask 클래스 변수
LongOperation LongOperationOdeme = new LongOperation();
그리고 AsyncTask를 방해하는 KEYCODE_BACK 액션
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
LongOperationOdeme.cancel(true);
}
return super.onKeyDown(keyCode, event);
}
그것은 나를 위해 작동합니다.