1. 程式人生 > >android 取消AsyncTask繼續執行的解決方案

android 取消AsyncTask繼續執行的解決方案

問題

當進入一個詳細頁面,這時程式會彈出一個對話方塊載入網路資料,可是發現使用者經常因為資料載入慢,就快速的退出這個頁面,這樣反覆來回幾次後,發現AsyncTask不再繼續載入,而是慢慢的等待,查了下個數,是前幾個沒有及時的關閉,導致當前的非同步任務一直在等待。

所以想請教如何在退出一個頁面後,也同時關閉對應的非同步任務?

初步解決程式碼方案:

public class Task extends AsyncTask<Void, Void, Void>{
@Override
protected Void doInBackground(Void... path) {
// Task被取消了,馬上退出迴圈
if(isCancelled()) return null;
}

@Override
public void onProgressUpdate(File... files) {
// Task被取消了,不再繼續執行後面的程式碼

if(isCancelled()) return;
.........
}
}

UI執行緒:

// 保持對Task的引用

private PhotoTask task;

// 1,啟動新的任務
task = new PhotoTask();
task.execute(path);

// 2, 取消任務

if (task != null && task.getStatus() == AsyncTask.Status.RUNNING) {
task.cancel(true); // 如果Task還在執行,則先取消它
}

}

}

解決方案的理論與解釋

  1. 設定Activity SingleTask 防止在開啟一個Activity的時候 新建一個物件

    1. 在Activity 銷燬的時候 使用AsyncTask . 取消的那個方法

    2. 自己寫一個AsynvTask

  2. 網友評論:載入網路資料、訪問資料庫、檔案等這些問題,應該另起一個執行緒並且後臺執行,不用讓使用者等待你的資料載入。
    回到你的問題上來,AsyncTask用的是執行緒池,執行緒不用就會放回池中. 有新的AsyncTask會取出已有執行緒,之後開始執行,這就是導致你有多個AsyncTask的原因。所以即使呼叫AsyncTask的cancle方法,你會發現依舊結束不了這個東西。


    你嘗試在關閉介面的同時獲得當前介面繫結的那個AsyncTask物件,並將其設定為空。如果依舊不行,那就可以考慮自己封裝一個下載執行緒啦

最後除錯後的程式碼

public class LoadPage extends AsyncTask<Void, Void, Void> {

        private volatile boolean running = true;

        private final ProgressDialog progressDialog;

        public LoadPage(Context ctx) {

            progressDialog = new ProgressDialog(ctx);

            progressDialog.setCancelable(true);

            progressDialog.setOnCancelListener(new OnCancelListener() {

                @Override

                public void onCancel(DialogInterface dialog) {

                    running = false;

                }

            });

        }

        @Override

        protected void onPreExecute() {

            progressDialog.show();

        }

        @Override

        protected void onCancelled() {

            running = false;

        }

        @Override

        protected Void doInBackground(Void... params) {

            while(running){

                // does the hard work one,two,three,

                Log.e("tag","run..");

            }

            Log.e("tag","exit");

            return null;

        }

        // ...

        @Override

        protected void onPostExecute(Void result) {

            super.onPostExecute(result);

        }

    }

總結:

經過上面的分析以及網友給出的具體建議,已經將問題解決了