zoukankan      html  css  js  c++  java
  • 一手遮天 Android

    项目地址 https://github.com/webabcd/AndroidDemo
    作者 webabcd

    一手遮天 Android - 异步和多线程: AsyncTask 的使用

    示例如下:

    /async/AsyncTaskDemo1.java

    /**
     * AsyncTask 的使用
     *
     * AsyncTask - 异步任务(用于简化“UI 线程启动一个后台线程,后台线程向 UI 线程通知进度并汇报结果”的场景)
     *     execute() - 执行
     *     cancel() - 取消
     *     getStatus() - 状态
     *         PENDING - AsyncTask 在调用 execute() 之前是 PENDING 状态
     *         RUNNING - AsyncTask 在调用 execute() 之后是 RUNNING 状态
     *         FINISHED - AsyncTask 在执行完成之后是 FINISHED 状态(注:在回调 onPostExecute() 或 onCancelled() 中仍然是 RUNNING 状态)
     *
     *     onPreExecute() - 任务执行前(UI 线程)
     *     doInBackground() - 执行任务(后台线程),接收“输入数据”,通知“进度通知”,返回“执行结果”
     *     onProgressUpdate() - 接收“进度通知”(UI 线程)
     *     onPostExecute() - 接收“执行结果”(UI 线程),如果调用了 AsyncTask 的 cancel() 则不会执行到这里
     *     onCancelled(boolean mayInterruptIfRunning) - 任务被取消(调用 AsyncTask 的 cancel() 后,等待后台线程执行完后才会回调)
     *         mayInterruptIfRunning 为 false 的方式:将 AsyncTask 的 isCancelled 状态置为 true,等任务执行完毕后回调 onCancelled() 方法(后台线程执行完后才会回调)
     *         mayInterruptIfRunning 为 true 的方式:将 AsyncTask 的 isCancelled 状态置为 true,调用线程的 interrupt() 方法,等任务执行完毕后回调 onCancelled() 方法(后台线程执行完后才会回调)
     *
     *
     * 注:
     * 1、只能在 UI 线程上实例化 AsyncTask 并调用其 execute() 方法
     * 2、该 cancel 的时候一定要 cancel(比如执行 AsyncTask 的 Activity 关闭的时候,记住一定要 cancel 掉 AsyncTask)
     * 3、取消线程时,如果线程中有 io 阻塞的话,先要把这个 io 干掉
     */
    
    package com.webabcd.androiddemo.async;
    
    import android.os.AsyncTask;
    import androidx.appcompat.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    
    import com.webabcd.androiddemo.R;
    
    public class AsyncTaskDemo1 extends AppCompatActivity {
    
        private Button _buttonExecute;
        private Button _buttonCancel1;
        private Button _buttonCancel2;
        private TextView _textView1;
        private TextView _textView2;
        private ProgressBar _progressBar1;
        private ProgressBar _progressBar2;
    
        private MyTask _myTask;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_async_asynctaskdemo1);
    
            _buttonExecute = (Button) findViewById(R.id.buttonExecute);
            _buttonCancel1 = (Button) findViewById(R.id.buttonCancel1);
            _buttonCancel2 = (Button) findViewById(R.id.buttonCancel2);
            _textView1 = (TextView) findViewById(R.id.textView1);
            _textView2 = (TextView) findViewById(R.id.textView2);
            _progressBar1 = (ProgressBar) findViewById(R.id.progressBar1);
            _progressBar2 = (ProgressBar) findViewById(R.id.progressBar2);
    
            sample();
        }
    
        private void sample() {
            _buttonExecute.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    // 实例化 AsyncTask(必须在 UI 线程)
                    _myTask = new MyTask();
    
                    // 执行 AsyncTask(必须在 UI 线程),同一个 AsyncTask 对象只能调用一次 execute()
                    _myTask.execute("myTask arg1", "myTask arg2"); // 这个参数为“输入数据”,其数据类型是在 AsyncTask 的泛型参数中定义的
                }
            });
    
            _buttonCancel1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 取消任务(mayInterruptIfRunning 为 false 的方式),将 AsyncTask 的 isCancelled 状态置为 true,等任务执行完毕后回调 onCancelled() 方法(后台线程执行完后才会回调)
                    _myTask.cancel(false);
                }
            });
    
            _buttonCancel2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 取消任务(mayInterruptIfRunning 为 true 的方式),将 AsyncTask 的 isCancelled 状态置为 true,调用线程的 interrupt() 方法,等任务执行完毕后回调 onCancelled() 方法(后台线程执行完后才会回调)
                    _myTask.cancel(true);
                }
            });
        }
    
        /**
         * 继承 AsyncTask 并实现相关逻辑
         * AsyncTask 有 3 个泛型参数,分别是“输入数据”,“进度通知”,“执行结果”,按需要指定其数据类型即可,如果不需要则用 java.lang.Void
         */
        private class MyTask extends AsyncTask<String, Integer, String> {
    
            // onPreExecute() - 任务执行前(UI 线程)
            @Override
            protected void onPreExecute() {
                _textView1.setText("异步任务准备执行");
            }
    
            // doInBackground() - 执行任务(后台线程),接收“输入数据”,通知“进度通知”,返回“执行结果”
            @Override
            protected String doInBackground(String... params) {
                // 接收“输入数据”
                writeMessage(String.format("异步任务开始执行:%s, %s", params[0], params[1]));
    
                try {
                    int i = 0;
                    int j = 0;
                    while (i < 100 || j < 100) {
                        Thread.sleep(10);
    
                        // 判断是否调用了 AsyncTask 的 cancel() 方法,如果被 cancel 了则需要像这样手动写退出线程的逻辑
                        if (isCancelled()) {
                            break;
                        }
    
                        i++;
                        if (i == 100) {
                            j += 10;
                            if (j == 100) {
                                break;
                            } else {
                                i = 0;
                            }
                        }
    
                        // 通知“进度通知”
                        publishProgress(i, j);
                    }
                } catch (InterruptedException e) {
                    writeMessage(e.toString());
                }
    
                // 返回“执行结果”
                return "ok";
            }
    
            // onProgressUpdate() - 接收“进度通知”(UI 线程)
            @Override
            protected void onProgressUpdate(Integer... progresses) {
                _progressBar1.setProgress(progresses[0]);
                _progressBar2.setProgress(progresses[1]);
                _textView1.setText(String.format("子任务进度:%d%%,总任务进度:%d%%", progresses[0], progresses[1]));
            }
    
            // onPostExecute() - 接收“执行结果”(UI 线程),如果调用了 AsyncTask 的 cancel() 则不会执行到这里
            @Override
            protected void onPostExecute(String result) {
                _textView1.setText("异步任务执行完毕: " + result);
                _progressBar1.setProgress(100);
                _progressBar2.setProgress(100);
            }
    
            // onCancelled() - 任务被取消(调用 AsyncTask 的 cancel() 后,等待后台线程执行完后才会回调)
            @Override
            protected void onCancelled() {
                _textView1.setText("异步任务已经取消");
                _progressBar1.setProgress(0);
                _progressBar2.setProgress(0);
            }
        }
    
        private void writeMessage(final String message) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    _textView2.append(String.format("%s
    ", message));
                }
            });
        }
    }
    
    

    /layout/activity_async_asynctaskdemo1.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <ProgressBar
            android:id="@+id/progressBar1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:progress="0"
            android:max="100"
            style="?android:attr/progressBarStyleHorizontal" />
    
        <ProgressBar
            android:id="@+id/progressBar2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:progress="0"
            android:max="100"
            style="?android:attr/progressBarStyleHorizontal" />
    
        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <Button
            android:id="@+id/buttonExecute"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="执行异步任务" />
    
        <Button
            android:id="@+id/buttonCancel1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAllCaps="false"
            android:text="取消(mayInterruptIfRunning 为 false 的方式)" />
    
        <Button
            android:id="@+id/buttonCancel2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAllCaps="false"
            android:text="取消(mayInterruptIfRunning 为 true 的方式)" />
    
        <TextView
            android:id="@+id/textView2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
    </LinearLayout>
    

    项目地址 https://github.com/webabcd/AndroidDemo
    作者 webabcd

  • 相关阅读:
    网站安全编程 黑客入侵 脚本黑客 高级语法入侵 C/C++ C# PHP JSP 编程
    【算法导论】贪心算法,递归算法,动态规划算法总结
    cocoa2dx tiled map添加tile翻转功能
    8月30日上海ORACLE大会演讲PPT下载
    【算法导论】双调欧几里得旅行商问题
    Codeforces Round #501 (Div. 3) B. Obtaining the String (思维,字符串)
    Codeforces Round #498 (Div. 3) D. Two Strings Swaps (思维)
    Educational Codeforces Round 89 (Rated for Div. 2) B. Shuffle (数学,区间)
    洛谷 P1379 八数码难题 (BFS)
    Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords (贪心)
  • 原文地址:https://www.cnblogs.com/webabcd/p/android_async_AsyncTaskDemo1.html
Copyright © 2011-2022 走看看