AsynTask

  • AsyncTask為什么要設計為只能夠一次任務?

因為要同一個實例執行多次很麻煩,沒必要。

假設允許多次 execute 同一個 AsyncTask 多次,也就是說隊列中會有同一個 AsyncTask 實例出現多次。首先 AsyncTask 需要改動很多,比如把各種狀態額外保存多份,不能像現在這樣簡單做為 AsyncTask 的成員變量,這些先不說,從調用者角度來看:

你繼承 AsyncTask 實現了自己的一個子類 MyTask,加了一些成員變量,你想多次執行同一個 MyTask,發現不對啊,我第一次執行后這些成員變量的值都變了,狀態不對。還得加個 reset 函數把這些值改回初使值,再一想何必呢,我干脆重新 new 一個 MyTask 不是更簡單有效嗎。

另外,雖然用默認的 Executor 是不會同時運行的,但你 execute 時如果用了自己定義 Executor,是有可能會多線程同時訪問的。這時你也會想還要搞線程同步太麻煩了還是我還是 new 兩個 MyTask 別想著同一個 MyTask 運行兩次好了。

所以,你看,就算人家允許你同一個 AsyncTask execute 多次,你既然也不會用這功能的話,我就干脆不許你 execute 兩次好了。

  • AsynTask造成的內存泄露的問題怎么解決,比如任務還在請求中,但這個Activity已經被銷毀了,這個task就仍然持有act的引用,造成內存泄露?

最主要的是在 Activity 銷毀時就應該把所有屬于這個 Activity 的 Task cancel 掉。

你的 Task 應該在 onCancelled 函數中做相應的處理。比如說如果 Task 是用 來聯網的,就應該在 onCancelled 中 disconnect。然后在 onCancelled 中將指向 Activity 的引用設為 null;

弱引用更多的是一份保險,保證如果你在沒有正確 cancel Task 時,不會讓本應去死的 Activity 還因為 Task 的引用還在內存中晃悠。當然這個保險是很有必要的。

弱引用Demo:

static class AsyncDrawable extends BitmapDrawable {
    private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;

    public AsyncDrawable(Resources res, Bitmap bitmap,
            BitmapWorkerTask bitmapWorkerTask) {
        super(res, bitmap);
        bitmapWorkerTaskReference =
            new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
    }

    public BitmapWorkerTask getBitmapWorkerTask() {
        return bitmapWorkerTaskReference.get();
    }
}
public void loadBitmap(int resId, ImageView imageView) {
    if (cancelPotentialWork(resId, imageView)) {
        final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
        final AsyncDrawable asyncDrawable =
                new AsyncDrawable(getResources(), mPlaceHolderBitmap, task);
        imageView.setImageDrawable(asyncDrawable);
        task.execute(resId);
    }
}

public static boolean cancelPotentialWork(int data, ImageView imageView) {
    final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);

    if (bitmapWorkerTask != null) {
        final int bitmapData = bitmapWorkerTask.data;
        // If bitmapData is not yet set or it differs from the new data
        if (bitmapData == 0 || bitmapData != data) {
            // Cancel previous task
            bitmapWorkerTask.cancel(true);
        } else {
            // The same work is already in progress
            return false;
        }
    }
    // No task associated with the ImageView, or an existing task was cancelled
    return true;
}

private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
   if (imageView != null) {
       final Drawable drawable = imageView.getDrawable();
       if (drawable instanceof AsyncDrawable) {
           final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
           return asyncDrawable.getBitmapWorkerTask();
       }
    }
    return null;
}

class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
    ...

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (isCancelled()) {
            bitmap = null;
        }

        if (imageViewReference != null && bitmap != null) {
            final ImageView imageView = imageViewReference.get();
            final BitmapWorkerTask bitmapWorkerTask =
                    getBitmapWorkerTask(imageView);
            if (this == bitmapWorkerTask && imageView != null) {
                imageView.setImageBitmap(bitmap);
            }
        }
    }
}

  • task執行完返回結果在已經被銷毀的act顯示,會如何?

如果執行了這個 activity 的 view 的操作的話,會報異常。因為此時這個 view 已經不屬于任何活的Window。

  • Act銷毀但Task如果沒有銷毀掉,當Act重啟時這個task該如何解決?

最多就是 Task 指向 Activity 的引用改成弱引用了。 Task 如果是 Activity 一個成員的話已經泄漏無法訪問了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,524評論 25 708
  • 介紹自己負責的部分,如何實現的。 自定義view viewGroup activity的啟動流程 事件傳遞及滑動沖...
    東經315度閱讀 1,248評論 1 4
  • Android開發者:你真的會用AsyncTask嗎? 導讀.1 在Android應用開發中,我們需要時刻注意保證...
    cxm11閱讀 2,730評論 0 29
  • 導讀:Android面試中高頻率出現的題都在這了。試題大部分從互聯網收集,博主下了一番功夫進行梳理總結,難免有不足...
    Maat紅飛閱讀 55,855評論 61 844
  • 總想寫點什么,卻不知從何寫起。每天心中都有個千萬個感慨,奈何無處發泄。從網絡中每天都能看到許多所謂的雞湯,其中的故...
    森叟閱讀 167評論 1 1