[java] Android-AsyncTask에 대한 시간 초과 설정?

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);

주 스레드 (일명 UI 스레드)에서 이것을 호출하면 실행이 차단되므로 별도의 스레드에서 호출해야 할 수 있습니다.


답변

이 경우 다운로더는 URL 연결을 기반으로하며 복잡한 코드없이 시간 제한을 정의하는 데 도움이되는 여러 매개 변수가 있습니다.

  HttpURLConnection urlc = (HttpURLConnection) url.openConnection();

  urlc.setConnectTimeout(15000);

  urlc.setReadTimeout(15000);

이 코드를 비동기 작업으로 가져 오면 괜찮습니다.

‘읽기 시간 초과’는 전송 중에 잘못된 네트워크를 테스트하는 것입니다.

‘연결 시간 초과’는 서버가 작동 중인지 여부를 테스트하기 위해 처음에만 호출됩니다.


답변

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 번 호출합니다. 모니터링을 추가하려는 경우 좋습니다.

이 페이지에서 얻은 모든 좋은 조언에 감사드립니다 🙂


답변

AsyncTask에 내장 된 것과 같은 것이 없다고 생각합니다. 당신의 접근 방식은 좋은 것 같습니다. AsyncTask의 doInBackground 메서드에서 isCancelled () 값을 주기적으로 확인하여 UI 스레드가이 메서드를 취소하면이 메서드를 종료하십시오.

어떤 이유로 핸들러를 사용하지 않으려면 AsyncTask 내에서 주기적으로 System.currentTimeMillis를 확인하고 시간 초과시 종료 할 수 있지만 실제로 스레드를 중단 할 수 있기 때문에 솔루션이 더 좋습니다.


답변

         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;
}