Android - 비동기 태스크의 타임아웃 설정
나는 가지고 있다.AsyncTask
웹 사이트에서 대량의 데이터 목록을 다운로드하는 클래스입니다.
최종 사용자가 사용 시 데이터 연결이 매우 느리거나 얼룩이 있는 경우, 이 경우,AsyncTask
일정 시간 경과 후 타임아웃합니다.이에 대한 나의 첫 번째 접근법은 다음과 같습니다.
MyDownloader downloader = new MyDownloader();
downloader.execute();
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
@Override
public void run() {
if ( downloader.getStatus() == AsyncTask.Status.RUNNING )
downloader.cancel(true);
}
}, 30000 );
를 기동한 후AsyncTask
, 새로운 핸들러가 기동하고, 이 핸들러가 기동하면,AsyncTask
30초 후에 작동하면 됩니다.
이게 좋은 방법인가요?아니면 그 안에 뭔가 들어있나요?AsyncTask
이 목적에 더 적합한가?
네, AsyncTask.get()이 있습니다.
myDownloader.get(30000, TimeUnit.MILLISECONDS);
이것을 메인 스레드(AKA)로 호출하는 것에 주의해 주세요.UI 스레드)가 실행을 차단합니다. 다른 스레드로 호출해야 할 수 있습니다.
onPreExecute() 메서드의 AsyncTask 확장 클래스에서 CountDownTimer 클래스를 사용합니다.
가장 큰 장점은 비동기 모니터링이 클래스에서 내부적으로 수행된다는 것입니다.
public class YouExtendedClass extends AsyncTask<String,Integer,String> {
...
public YouExtendedClass asyncObject; // as CountDownTimer has similar method -> to prevent shadowing
...
@Override
protected void onPreExecute() {
asyncObject = this;
new CountDownTimer(7000, 7000) {
public void onTick(long millisUntilFinished) {
// You can monitor the progress here as well by changing the onTick() time
}
public void onFinish() {
// stop async task if not in progress
if (asyncObject.getStatus() == AsyncTask.Status.RUNNING) {
asyncObject.cancel(false);
// Add any specific task you wish to do as your extended class variable works here as well.
}
}
}.start();
...
예를 들어 CountDownTimer(7000, 7000) -> CountDownTimer(7000, 1000)를 변경하면 onFinish()를 호출하기 전에 onTick()을 6회 호출합니다.모니터링을 추가할 경우 이 방법이 좋습니다.
이 페이지에서 좋은 조언을 해주셔서 감사합니다:-)
이 경우 다운로더가 URL 접속을 기반으로 하기 때문에 복잡한 코드를 사용하지 않고 타임아웃을 정의할 수 있는 파라미터가 다수 있습니다.
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setConnectTimeout(15000);
urlc.setReadTimeout(15000);
이 코드를 비동기 태스크로 가져오기만 하면 됩니다.
「Read Timeout(읽기 타임 아웃)」은, 전송중에 불량 네트워크를 테스트합니다.
"Connection Timeout"은 서버가 가동 중인지 여부를 테스트하기 위해 처음에만 호출됩니다.
비동기 태스크에는 그런 기능이 포함되어 있지 않은 것 같습니다.당신의 접근법은 좋은 것 같습니다.UI 스레드에 의해 취소된 후 이 메서드를 종료하려면 AsyncTask의 doInBackground 메서드에서 isCancelled() 값을 정기적으로 확인하십시오.
어떤 이유로든 핸들러를 사용하지 않으려면 System.current TimeMillis를 정기적으로 체크하고 타임아웃 시 종료할 수 있습니다.단, 실제로는 스레드가 중단될 수 있기 때문에 솔루션이 더 좋습니다.
Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
//async task
final RunTask tsk = new RunTask ();
tsk.execute();
//setting timeout thread for async task
Thread thread1 = new Thread(){
public void run(){
try {
tsk.get(30000, TimeUnit.MILLISECONDS); //set time in milisecond(in this timeout is 30 seconds
} catch (Exception e) {
tsk.cancel(true);
((Activity) mContext).runOnUiThread(new Runnable()
{
@SuppressLint("ShowToast")
public void run()
{
Toast.makeText(mContext, "Time Out.", Toast.LENGTH_LONG).show();
finish(); //will close the current activity comment if you don't want to close current activity.
}
});
}
}
};
thread1.start();
}
한 가지 조건을 추가하여 취소를 강화할 수 있습니다. 예를 들어,
if (downloader.getStatus() == AsyncTask.Status.RUNNING || downloader.getStatus() == AsyncTask.Status.PENDING)
downloader.cancel(true);
질문에서 영감을 얻어 AsyncTask를 통해 백그라운드 작업을 수행하는 방법을 작성했습니다.처리에 LOADING_TIMEOUT보다 시간이 더 걸리면 재시도하라는 경고 대화상자가 나타납니다.
public void loadData()
{
final Load loadUserList=new Load();
loadUserList.execute();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (loadUserList.getStatus() == AsyncTask.Status.RUNNING) {
loadUserList.cancel(true);
pDialog.cancel();
new AlertDialog.Builder(UserList.this)
.setTitle("Error..!")
.setMessage("Sorry you dont have proper net connectivity..!\nCheck your internet settings or retry.")
.setCancelable(false)
.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
loadData();
}
})
.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
System.exit(0);
}
})
.show();
}
}
}, LOADING_TIMEOUT);
return;
}
언급URL : https://stackoverflow.com/questions/7882739/android-setting-a-timeout-for-an-asynctask
'IT' 카테고리의 다른 글
for-of-loop 내부 ES6 어레이 요소 인덱스 액세스 (0) | 2022.10.29 |
---|---|
설치된 판다 버전을 찾는 방법 (0) | 2022.10.29 |
loopback: 리모트 DB가 아닌 로컬 DB로 값이 전송되도록 하려면 어떻게 해야 합니까? (0) | 2022.10.29 |
JSDoc: 개체 구조를 반환합니다. (0) | 2022.10.29 |
배열에서 스트리밍할 때 정수를 문자열에 매핑할 수 없는 이유는 무엇입니까? (0) | 2022.10.29 |