AsyncTask アンチパターン

19
AsyncTask アンチパターン 2014-12-04 Android アンチパターン勉強会 黒川 / @hydrakecat

Transcript of AsyncTask アンチパターン

  • AsyncTask 2014-12-04 Android

    / @hydrakecat

  • AsyncTask ...

  • Android Thread Looper

    Processes and Threads | Android DevelopersHandling Runtime Changes | Android DevelopersEfficient Android Threading (Anders Goransson)

  • Android View UI UI 5 ANR (Application Not Responding)

  • Android Basic ThreadHandlerThreadExecutorAsyncTaskServicesAsyncQueryHandlerLoader

  • Android Basic ThreadHandlerThreadExecutorAsyncTaskServicesAsyncQueryHandlerLoader

  • AsyncTask http://developer.android.com/reference/android/os/AsyncTask.html UI Thread Handler Executor AsyncTask

  • AsyncTask 1@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... new AsyncTask(){ @Override protected void onPreExecute() { super.onPreExecute(); mProgressDialog.show(); } @Override protected String doInBackground(Void... value) { try { Thread.sleep(15000); } catch (InterruptedException e) { } return "AsyncTask Done"; } @Override protected void onPostExecute(String result) { mProgressDialog.dismiss(); mTextView.setText(result); } }.execute();

  • IllegalArgumentException Configuration Chage Activity Fragment detach mProgressDialog.dismiss() IllegalArgumentException ConfigurationChange

  • IllegalArgumentException

    onDestroy null @Override public void onCreate(Bundle savedInstanceState) { ... new AsyncTask(){ ... @Override protected void onPostExecute(String result) { if (mProgressDialog != null) { mProgressDialog.dismiss(); } if (mTextView != null) { mTextView.setText(result); } } }.execute(); } @Override public void onDestroy() { if (mProgressDialog != null && mProgressDialog.isShowing()) { mProgressDialog.dismiss(); } mProgressDialog = null; }

    ProgressDialog !

  • Configuration change Activity AsyncTask Thread AsyncTaskLoader Activity

  • AsyncTask 2Fragment#getActivity() null Configuration Chage Fragment detach

    @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ... new AsyncTask(){ ... @Override protected void onPostExecute(String[] result) { mAdapter = new ArrayAdapter(getActivity(), R.layout.listrow, result); mListView.setAdapter(mAdapter); } }.execute(); }

  • NullPointerException Fragment#isAdded() mAdapter @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ... new AsyncTask(){ ... @Override protected void onPostExecute(String[] result) { if (isAdded() && mAdapter != null) { mAdapter.addAll(Arrays.asList(result)); mAdapter.notifyDatasetChanged(); } } }.execute(); }

  • AsyncTask 3

    task = new AsyncTask(){ ...}.execute();

    non-static ActivityAsyncTask GC

    : Efficient Android Threading

  • non-static static Activity#onDestory() Activity AsyncTask#cancel() Activity Weak Reference@Override public void onCreate(Bundle savedInstanceState) { ... mTask = new MyTask(this); mTask.execute();}

    @Override protected void onDestroy () { super.onDestroy(); mTask.setActivity(null); mTask.cancel(true);}

    private static class MyTask extends AsyncTask { ...}

  • AsyncTask#cancel(false)isCanceledtrueAsyncTask#cancel(true)private static class MyTask extends AsyncTask { @Override protected String doInBackground(Void... params) { for (int i=0; i
  • AsyncTask 4AsyncTask sequentialconcurrentAPI Service AsyncTask Activity AsyncTask

    API targetSdkVersion execute executeOnExecutor1-3 Any Sequential Not available4-10 Any Concurrent Not available11-12 Any Concurrent Sequential/Concurrent (customizable)13+

  • API

    2.3AsyncTasktargetSdkVersion < 13 API

    if (Build.VERSION.SDK_INT

  • AsyncTask

    non-static inner class Activity#onDestroy() Activity AsyncTaskLoader Executor HandlerThread