Android_AyscnTask

Posted HJ0101

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android_AyscnTask相关的知识,希望对你有一定的参考价值。

背景:

  在android中实现异步任务机制有两种方式:Handle和AsycnTask

  在Handle模式中,需要为每一个异步任务创建一个新的线程,任务完成后通过Handel实例setMessage向UI线程发送消息,完成UI界面的更新.这种方式对于整个过程而言,控制比较精细,结构相对清晰,但是代码相对复杂,当有多个异步任务同时执行时,不易对线程进行精确的控制.

  为了简化操作,官方提供工具类android.os.AsyncTask,它使创建异步任务变得更加简单,不再需要编写任务线程和Handler实例即可完成相同的任务。

定义一个AsycnTask:

 static class MyAsycnTask extends AsyncTask<String,Integer,Boolean>{}

它的参数是泛型,分别代表"启动任务时传入的参数","后台任务执行的进度","执行完成后返回结果类型",当然如果你不需要使用,可以使用void代替.

定义AsycnTask;必须重写protected Boolean doInBackground(String... strings)用于执行后台任务

 public static class MyAsycnTask extends AsyncTask<String,Integer,String>  {

        //异步任务执行前的准备工作  UI线程
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }
        //执行异步任务  子线程
        @Override
        protected String doInBackground(String... strings) {
            return null;
        }
        //异步任务完成后执行  UI线程
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
        }
        //更新后台任务进度 UI线程
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
        }
        //当任务取消时执行
        @Override
        protected void onCancelled(String s) {
            super.onCancelled(s);
        }
    }

Demo:实现异步下载操作,并更新进度,以及取消下载任务

public class MainActivity extends AppCompatActivity {

    protected static TextView textView;
    protected Button button1;
    protected Button button2;
    protected static ProgressBar progressBar;
    protected MyAsycnTask myasycnTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //调用execute触发异步任务执行
                myasycnTask = new MyAsycnTask();
                myasycnTask.execute();
            }
        });
        findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //调用cancel,取消线程任务
                myasycnTask.cancel(false);
                textView.setText("已暂停下载");
            }
        });
        initView();
    }

    public void initView() {
        textView = findViewById(R.id.textView);
        button1 = findViewById(R.id.button);
        button2 = findViewById(R.id.button2);
        progressBar = findViewById(R.id.progressBar);
    }

    static class MyAsycnTask extends AsyncTask<String, Integer, Boolean> {

        //下载前的准备 UI线程
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            textView.setText("正在下载中");
            progressBar.setProgress(0);
        }

        //开始下载任务 子线程
        @Override
        protected Boolean doInBackground(String... strings) {
            try {
                if (!isCancelled()) {
                    URL url = new URL("https://clfile.imooc.com/class/assist/119/4289211/Handler%E6%BA%90%E7%A0%81(%E4%BB%A3%E7%A0%81%E7%BB%8F%E8%BF%87%E5%B0%81%E8%A3%85).rar");
                    URLConnection connection = url.openConnection();
                    InputStream inputStream = connection.getInputStream();
                    //获取文件总长度
                    int fileContent = connection.getContentLength();
                    //设置文件夹路径
                    String fileName = Environment.getExternalStorageDirectory() + File.separator + "2018.7.27";
                    File file = new File(fileName);
                    if (file.exists()) {
                        file.delete();
                    }
                    //文件已下载长度
                    int fileLength = 0;
                    int len = 0;
                    byte[] b = new byte[1024];
                    OutputStream outputStream = new FileOutputStream(fileName);
                    while ((len = inputStream.read(b)) != -1) {
                        outputStream.write(b, 0, len);
                        fileLength += len;
                        publishProgress(fileLength * 100 / fileContent);
                    }
                    inputStream.close();
                    outputStream.close();
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return true;
        }

        //下载完成后执行的操作  UI线程
        @Override
        protected void onPostExecute(Boolean aBoolean) {
            super.onPostExecute(aBoolean);
            textView.setText("下载完成" + aBoolean);
        }

        //更新后台进度 UI线程
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            if (values != null && values[0] > 0) {
                progressBar.setProgress(values[0]);
            }
        }
    }
}

获取权限:manifests

  <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

效果图展示:

 

注意事项:

1.异步任务的实例必须在UI线程中创建

2.execute方法必须在UI线程中调用

3.不要手动的调用onPreExecute(),doInBackground(Params... params),onProgressUpdate(Progress... values),onPostExecute(Result result)这几个方法。

4.不能在doInBackground(Params... params)中修改UI信息

5.一个任务实例只能执行一次,如果执行第二次则会抛出异常

6.当有多个任务需要执行性时,按顺序一个一个执行

 

以上是关于Android_AyscnTask的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段——声明函数