1. 程式人生 > >Android中如何巧妙停止執行緒的方法

Android中如何巧妙停止執行緒的方法

好長時間沒更新部落格了,最近聽取別人的部落格寫作經驗,將開發中遇到的問題進行分享也是原創。這是去年的網約車專案中遇到的。
在處理多執行緒任務時,比如倒計時接單(通過子執行緒實現倒計時),新來訂單15s後自動消失。而業務需求中又要允許使用者在倒計時未結束時手動劃掉消失,則此時需要停止倒計時執行緒。或者可能有時有多單依次疊加,此時最上面的一單消失時,也需要先停止上一單倒計時再自動開啟下一單的倒計時。
如果是new Thread方式的interrupt()方法來停止執行緒,你列印時輸出會發現倒計時中累加的變數並未停止累加。箇中原因參看停止Java執行緒,小心interrupt()方法
萬般無奈中想起AsyncTask不是自帶執行緒停止方法麼,即taskProgress.cancel(true)(taskProgress是TaskProgress繼承AsyncTask後新new的物件),並且自帶判斷執行緒是否正在執行的方法taskProgress.getStatus() == AsyncTask.Status.RUNNING,果斷解決問題。程式碼如下:
     /*
     * 新來訂單時開始計時
     */
    public static TaskProgress taskProgress;
    public void startCountdown(final int mProgress, final int maxtime) {
        if (maxtime > 0) {
            roundProgressBar.setVisibility(View.VISIBLE);

            if (taskProgress != null && taskProgress.getStatus() == AsyncTask.Status.RUNNING)  
            {  
                taskProgress.cancel(true
); // 如果Task還在執行,則先取消它,然後執行關閉activity程式碼 taskProgress = null; } taskProgress = new TaskProgress(maxtime); taskProgress.execute(0); } } /* * 開啟倒計時,倒計時任務需要能手動停止,故而用AsyncTask,Thread無法在左右滑動卡片時停止執行緒 */ public class TaskProgress extends AsyncTask<Integer, Integer, Integer> {// 繼承AsyncTask
int maxtime; int mProgress; public TaskProgress(int maxtime) { this.maxtime = maxtime; } @Override protected Integer doInBackground(Integer... params) {// 處理後臺執行的任務,在後臺執行緒執行 int flag = 1; if (isCancelled()) return null; mProgress = params[0]; while (mProgress <= maxtime && !isCancelled()) { try { publishProgress(mProgress);//將會呼叫onProgressUpdate(Integer... progress)方法 mProgress += 1; Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } LogUtils.e("-----------------------", String.valueOf(mProgress)); LogUtils.e("-----------------------", String.valueOf(mProgress)); LogUtils.e("-----------------------", String.valueOf(mProgress)); } return flag; } protected void onProgressUpdate(Integer... progress) {// 在呼叫publishProgress之後被呼叫,在ui執行緒執行 // roundProgressBar.setProgress(progress[0]);//更新進度條的進度 if (isCancelled()) { return; } else { roundProgressBar.setProgress(progress[0], maxtime); } } protected void onPostExecute(Integer result) {// 後臺任務執行完之後被呼叫,在ui執行緒執行 if (result != null) { //自動消失 MainActivity.getInstance().vanishOnDisappear(); } } protected void onPreExecute() {// 在doInBackground(Params...)之前被呼叫,在ui執行緒執行 roundProgressBar.setProgress(0, maxtime);// 進度條復位 } protected void onCancelled() {// 在ui執行緒執行 // roundProgressBar.setProgress(0, maxtime);// 進度條復位 } }

剩下的問題時,為什麼這個非同步任務的執行緒可以通過cancel方法停止呢?未完待續……..因為我還沒看原始碼深究@[email protected]