笔记16 | 解析和练习AsyncTask

前言

本节给大家带来的是Android给我们提供的一个轻量级的用于处理异步任务的类:AsyncTask,我们一般是 继承AsyncTask,然后在类中实现异步操作,然后将异步执行的进度,反馈给UI主线程~

地址

http://blog.csdn.net/xiangyong_1521/article/details/50516055

目录

  • 相关概念
  • AsyncTask全解析
  • AsyncTask使用示例播放进度示例

一.相关概念

1)什么是多线程:

  • 应用程序(Application):为了完成特定任务,用某种语言编写的一组指令集合(一组静态代码)
  • 进程(Process) :运行中的程序,系统调度与资源分配的一个独立单位,操作系统会为每个进程分配 一段内存空间,程序的依次动态执行,经理代码加载 -> 执行 -> 执行完毕的完整过程!
  • 线程(Thread):比进程更小的执行单元,每个进程可能有多条线程,线程需要放在一个进程中才能执行! 线程是由程序负责管理的!!!而进程则是由系统进行调度的!!!
  • 多线程概念(Multithreading):并行地执行多条指令,将CPU的时间片按照调度算法,分配给各个线程,实际上是分时执行的,只是这个切换的时间很短,用户感觉是同时而已!

2)同步与异步的概念:

  • 同步:当我们执行某个功能时,在没有得到结果之前,这个调用就不能返回!简单点就是说必须 等前一件事做完才能做下一件事;举个简单的例子:比如你啪啪啪,为了避免弄出人命,肯定要先戴好套套, 然后再啪啪啪是吧~套套戴好 -> 然后啪啪啪,比如你没套套,那啪啪啪的操作就要等待了,直到你把 套套买回来带上,这个时候就可以开始啪啪啪了~一个形象地例子,♪(^∇^*)
  • 异步:和同步则是相对的,当我们执行某个功能后,我们并不需要立即得到结果,我们额可以正常地 做其他操作,这个功能可以在完成后通知或者回调来告诉我们;还是上面那个后台下载的例子,后台下载, 我们执行下载功能后,我们就无需去关心它的下载过程,当下载完毕后通知我们就可以了~

3) Android为很么要引入异步任务

因为Android程序刚启动时,会同时启动一个对应的主线程(Main Thread),这个主线程主要负责处理 与UI相关的事件!有时我们也把他称作UI线程!而在Android App时我们必须遵守这个单线程模型的规则: Android UI操作并不是线程安全的并且这些操作都需要在UI线程中执行! 假如我们在非UI线程中,比如在主线程中new Thread()另外开辟一个线程,然后直接在里面修改UI控件的值; 此时会抛出下述异常:

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views 

另外,还有一点,如果我们把耗时的操作都放在UI线程中的话,如果UI线程超过5s没有响应用于请求,那么 这个时候会引发ANR(Application Not Responding)异常,就是应用无响应~ 最后还有一点就是:Android 4.0后禁止在UI线程中执行网络操作~不然会报:

android.os.NetworkOnMainThreadException

以上的种种原因都说明了Android引入异步任务的意义,当然实现异步也不可以不用到我们本节讲解 的AsyncTask,我们可以自己开辟一个线程,完成相关操作后,通过下述两种方法进行UI更新:

  • 前面我们学的Handler,我们在Handler里写好UI更新,然后通过sendMessage()等的方法通知UI 更新,另外别忘了Handler写在主线程和子线程中的区别哦~
  • 利用Activity.runOnUiThread(Runnable)把更新ui的代码创建在Runnable中,更新UI时,把Runnable 对象传进来即可~

二.AsyncTask全解析

1)为什么要用AsyncTask?

我们可以用上述两种方法来完成我们的异步操作,加入要我们写的异步操作比较多,或者较为繁琐, 难道我们new Thread()然后用上述方法通知UI更新么?程序员都是比较喜欢偷懒的,既然官方给我们提供了AsyncTask这个封装好的轻量级异步类,为什么不用呢?我们通过几十行的代码就可以完成我们的异步操作,而且进度可控;相比起Handler,AsyncTask显得更加简单,快捷~当然,这只适合简单的异步操作,另外,实际异步用的最多的地方就是网络操作,图片加载,数据传输等,AsyncTask暂时可以满足初学者的需求,谢谢小应用,但是到了公司真正做项目以后,我们更多的使用第三发的框架,比如Volley,OkHttp,android-async-http,XUtils等很多,后面进阶教程我们会选1-2个框架进行学习,当然你可以自己找资料学习学习,但是掌握AsyncTask还是很有必要的!

2)AsyncTask的基本结构:

AsyncTask是一个抽象类,一般我们都会定义一个类继承AsyncTask然后重写相关方法~ 官方API:AsyncTask

  • 构建AsyncTask子类的参数:
  • 相关方法与执行流程:
  • 注意事项:

3.AsyncTask使用示例:播放进度示例

  • APP界面
  • XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"      xmlns:tools="http://schemas.android.com/tools"      android:layout_width="match_parent"      android:layout_height="match_parent"      android:orientation="vertical"      tools:context=".MainActivity" >      <TextView          android:id="@+id/textView1"          android:layout_width="wrap_content"          android:layout_height="wrap_content" />      <SeekBar          android:id="@+id/seekBar1"          android:layout_width="match_parent"          android:layout_height="wrap_content" />      <Button          android:id="@+id/button1"          android:layout_width="match_parent"          android:layout_height="wrap_content"          android:text="播放" />  </LinearLayout>  
  • MyAsyncTask.java
public class MyAsyncTask extends AsyncTask<Integer,Integer,String>{      private TextView  txt;      private SeekBar seekBar;      public MyAsyncTask(TextView txt, SeekBar seekBar) {          super();          this.txt=txt;          this.seekBar=seekBar;      }      //该方法不运行在UI线程中,主要用于异步操作,通过调用publishProgress()方法        //触发onProgressUpdate对UI进行操作        @Override      protected String doInBackground(Integer... params) {          int i=0;          try {              DelayOperator dop=new DelayOperator();              for(i=10;i<=1000;i+=10)              {                  dop.delay();                  publishProgress(i);              }          } catch (Exception e) {          }          return i+params[0].intValue()+"";      }       //该方法运行在UI线程中,可对UI控件进行设置       @Override      protected void onPreExecute() {          try {              txt.setText("正在播放");          } catch (Exception e) {              e.printStackTrace();          }      }      @Override      protected void onProgressUpdate(Integer... values) {          int value=values[0];          seekBar.setProgress(value);      }  } 
  • DelayOperator.java
package com.example.text_ansynctask;  public class DelayOperator {      public void delay(){          try {              Thread.sleep(1000);          } catch (Exception e) {              e.printStackTrace();          }      }  }  
  • MainActivity.java
public class MainActivity extends Activity {      private Button button;      private TextView textView;      private SeekBar seekBar;      @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);          button=(Button) findViewById(R.id.button1);          textView=(TextView) findViewById(R.id.textView1);          seekBar=(SeekBar) findViewById(R.id.seekBar1);          button.setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {                  MyAsyncTask myTask=new MyAsyncTask(textView,seekBar);                  Toast.makeText(MainActivity.this, "开始播放", 1).show();                  myTask.execute(1000);              }          });      }  }  

原文发布于微信公众号 - 项勇(xiangy_life)

原文发表时间:2017-10-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏吴小龙同學

Android之进程和线程

进程 线程 应用启动时,系统会为应用创建一个名为“主线程”的执行线程。 此线程非常重要,因为它负责将事件分派给相应的用户界面小工具,其中包括绘图事件。 此外,它...

3096
来自专栏Android小菜鸡

搭建一个MVP框架

  MVP是一种设计模式,是MVC模式的一种演变。他出现的主要目的是划分代码模块职责,降低模块耦合度,易于单元测试。

984
来自专栏Linyb极客之路

Java常用日志框架介绍

看了上面的介绍是否会觉得比较混乱,这些日志框架之间有什么异同,都是由谁在维护? 下文会逐一介绍。

1201
来自专栏我就是马云飞

得到Android团队无埋点方案

概述 客户端埋点是数据收集的最基本手段,但由于业务迭代速度很快,手动埋点方案虽然灵活多变,但是极大的增加了客户端开发人员的工作量。开发完成业务功能需要花费很大...

4419
来自专栏微信公众号:Java团长

Java常用日志框架介绍

看了上面的介绍是否会觉得比较混乱,这些日志框架之间有什么异同,都是由谁在维护? 下文会逐一介绍。

732
来自专栏java一日一条

15 个 Android 通用流行框架大全

Android自带很多测试工具:JUnit,Monkeyrunner,UiAutomator,Espresso等

732
来自专栏项勇

笔记 33 | Android通信之Thread类实现多线程

1615
来自专栏7号代码

Android开发高级进阶——Service与Notification

Service是处理一些后台任务,在主线程中,并不能执行耗时操作。而Thread是开启一个子线程,在子线程中执行耗时操作,这样不会阻塞主线程。

904
来自专栏静晴轩

Android子线程更新UI主线程方法之Handler

我们开发应用程序的时候,处于线程安全的原因子线程通常是不能直接更新主线程(UI线程)中的UI元素的,那么在Android开发中有几种方法解决这个问题,其中方法之...

3418
来自专栏yang0range

MVC的介绍与实践

Controller控制器则由Activity承担,一般情况下会在Activity中获取数据以及界面元素,并将两者进行保定,但是其逻辑不能过于复杂。

662

扫码关注云+社区