Android非同期タスク-ASyncTask

6586 ワード

Android-Handlerのメッセージングメカニズムを簡単に紹介したが,質量数を計算するdemoはサブHandlerを用いてTextViewを計算し更新する際に非常に複雑である.Androidは、非同期タスク(AsyncTask)というもう一つの簡略化された方法を提供しています.相対的にAsyncTaskはより軽量で,簡単な非同期処理に適している.
AsyncTaskを用いて開発された計算素数demoを見てみましょう.Javaコードは以下の通りです.
public class AsyncTaskActivity extends AppCompatActivity {
    private TextView tv_calculate_result;
    private EditText edit_number;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_async_task);
        tv_calculate_result = (TextView) findViewById(R.id.tv_calculate_result);
        edit_number = (EditText) findViewById(R.id.edit_number);
        findViewById(R.id.btn_calculate).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (TextUtils.isEmpty(edit_number.getText().toString().trim())) {
                    Toast.makeText(AsyncTaskActivity.this, "     ", Toast.LENGTH_SHORT).show();
                } else {
                    CalculateTask calculateTask = new CalculateTask();
                    calculateTask.execute(edit_number.getText().toString().trim());
                }
            }
        });
    }

    private class CalculateTask extends AsyncTask{


        @Override
        protected String doInBackground(String... params) {
            int upper = Integer.parseInt(params[0]);
            List nums = new ArrayList<>();
            //   2  , upper     
            outer:
            for (int i = 2; i <= upper; i++) {
                // i   2  , i        
                for (int j = 2; j <= Math.sqrt(i); j++) {
                    //      ,          
                    if (i != 2 && i % j == 0) {
                        continue outer;
                    }
                }
                nums.add(i);
            }
            return nums.toString();
        }

        @Override
        protected void onPostExecute(String s) {
            tv_calculate_result.setText(s);
        }
    }
}

実行効果:
质数を计算するgif
AsyncTaskについてはdoInBackground()とonPostExecute()の2つの方法を主に書き換えて,我々の以前の問題を解決した.
AsyncTask抽象クラス
AsyncTaskは抽象クラスであり、通常は継承に使用され、継承時に3つの汎用パラメータを指定する必要があります.
  • Params:タスク実行を開始する入力パラメータのタイプ.
  • Progress:バックグラウンドタスク完了の進捗値タイプ.
  • Result:バックグラウンドでタスクが完了した後に結果を返すタイプ.

  • AsyncTaskの使用方法
    AsyncTaskを使うには3ステップだけです.
  • AsyncTaskのサブクラスを作成し、3つの汎用パラメータのタイプを指定します.指定が不要な場合はVoidに設定します.
  • 必要に応じてAsyncTaskを実現するための以下の方法.

  • doInBackground(Params...):バックグラウンドスレッドが完了するタスク.このメソッドは、publishProgress(Progress...values)メソッドを呼び出して、タスクの実行進捗を更新します.onProgressUpdate(Progress...values):doInBackground()でpublishProgress()メソッドを呼び出してタスクの実行進捗を更新すると、このメソッドがトリガーされます.onPreExecute():バックグラウンドの時間のかかる操作を実行する前に呼び出されます.通常、インタフェースに進捗バーを表示するなど、初期化の準備を完了するために使用されます.onPostExecute(Result result):doInBackground()が完了すると、このメソッドが自動的に呼び出され、doInBackground()の戻り値がメソッドに渡されます.
  • AsyncTaskサブクラスのインスタンスを呼び出すexecute(Params...params)は、時間のかかるタスクの実行を開始する.

  • AsyncTaskが遵守するルールの使用
  • UIスレッドにAsyncTaskのインスタンスを作成する必要があります.
  • UIスレッドでAsyncTaskのexecute()メソッドを呼び出す必要があります.
  • AsyncTaskのdoInBackground(Params...)、onProgressUpdate(Progress...values)、onPreExecute()、onPostExecute(Result result)メソッドは、プログラマコード呼び出しがあるべきではなく、Androidシステムが呼び出しを担当する.
  • AsyncTaskは1回のみ実行され、複数回の呼び出しで例外が発生します.

  • 以下に、非同期タスクを使用してダウンロードを実行する例を示します.コードは次のとおりです.
    public class AsyncTaskActivity extends AppCompatActivity {
        private TextView tv_show;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_async_task);
            tv_show = (TextView) findViewById(R.id.tv_show);
            findViewById(R.id.btn_down).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    DownTask downTask = new DownTask(AsyncTaskActivity.this);
                    try {
                        downTask.execute(new URL("http://www.jianshu.com/p/e807eb8c31f0"));
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        private class DownTask extends AsyncTask {
            //        , AsyncTask.execute()  
            ProgressDialog pdialog;
            //           
            int hasRead = 0;
            Context mContext;
    
            public DownTask(Context ctx) {
                mContext = ctx;
            }
    
            @Override
            //           
            protected String doInBackground(URL... params) {
                StringBuilder sb = new StringBuilder();
                try {
                    URLConnection conn = params[0].openConnection();
                    //  conn        ,      BufferedReader
                    BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
                    String line;
                    while ((line = br.readLine()) != null) {
                        sb.append(line).append("
    "); hasRead++; publishProgress(hasRead);// } return sb.toString(); } catch (IOException e) { e.printStackTrace(); } return null; } @Override // doInBackground() doInBackground() protected void onPostExecute(String s) { // HTML tv_show.setText(s); pdialog.dismiss(); } @Override // protected void onPreExecute() { pdialog = new ProgressDialog(mContext); pdialog.setTitle(" ..."); pdialog.setMessage(" , ..."); pdialog.setCancelable(false); pdialog.setMax(202); pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); pdialog.setIndeterminate(false);// pdialog.show(); } @Override // doInBackground() publishProgress() protected void onProgressUpdate(Integer... values) { // tv_show.setText(" 【" + values[0] + "】 !"); pdialog.setProgress(values[0]); } } }

    実行効果:
    Webコードをダウンロードします.gif
    参考記事
  • 『クレイジーandroid講義』(第3版)第3章3.6非同期タスク