聽起來是個很有用的東西,但可惜的是它隱藏的問題其實也不少,其中一個就是它很容易造成 memroy leak
通常使用 AsyncTask 時,都會用 non-static inner class 來使用,因為這樣可以很方便的引用 outer class 裡面的欄位,例如下面一個簡單的例子
public class MainActivity extends Activity {
private Object mMyObject;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// Somewhere the AsyncTask is started
public class MyAsyncTask extends AsyncTask<Void, Void, String> {
@Override protected String doInBackground(Void... params) {
// Do work
longRunningProcess();
return result;
}
@Override protected void onPostExecute(String result) {
Log.d("Object: " + mMyObject.toString());
Log.d("MyAsyncTask", "Received result: " + result);
}
}
}
但是,當你用 non-static inner class 來使用 AsyncTask 的時候,你就有可能造成 memroy leak,因為 non-static inner class 會隱式的持有對 outer 的 reference,例如在這個例子中 MyAsyncTask 就會持有 MainActivity 的 reference,若是在 longRunningProcess 函式操作途中 MainActivity 被銷毀的話,MainActivity 會因為被 MyAsyncTask 持有 reference 而無法被 GC 回收,造成 memory leak那我們要怎樣避免 AsyncTask memory leak,就是
public class MainActivity extends Activity {
private Object mMyObject;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// Somewhere the AsyncTask is started
public static class MyAsyncTask extends AsyncTask<Void, Void, String> {
private WeakReference<MainActivity> mActivity;
public MyAsyncTask(MainActivity activity) {
mActivity = new WeakReference<>(activity);
}
@Override protected String doInBackground(Void... params) {
// Do work
longRunningProcess();
return result;
}
@Override protected void onPostExecute(String result) {
MainActivity activity = mActivity.get();
if (activity == null || activity.isFinishing())
return;
Log.d("Object: " + mMyObject.toString());
Log.d("MyAsyncTask", "Received result: " + result);
}
}
}
memory leak 只是 AsyncTask 的一個常見的坑之一,網路上找一找會發現它的坑還有很多,限制也不少,Android 本意是要提供一個好用方便的 class,讓開發者不用煩惱 background thread 跟 UI thread 交互作用的問題,專注於開發業務邏輯,但現在反而開發者要注意更多 AsyncTask 的坑與細節,看起來也並沒有減少多少開發者的工作量
沒有留言:
張貼留言