事件处理机制之AnsyncTask异步任务

(一)概述

本节给大家带来的是Android给我们提供的一个轻量级的用于处理异步任务的类:AsyncTask,我们一般是 继承AsyncTask,然后在类中实现异步操作,然后将异步执行的进度,反馈给UI主线程~ 好吧,可能有些概念大家不懂,觉得还是有必要讲解下多线程的概念,那就先解释下一些概念性的东西吧!

(二)AnsyncTask异步任务

1.相关概念

1)什么是多线程:

答:先要了解这几个名称:应用程序,进程,线程,多线程!!

应用程序(Application):为了完成特定任务,用某种语言编写的一组指令集合(一组静态代码)

进程(Process) :运行中的程序,系统调度与资源分配的一个独立单位,操作系统会为每个进程分配 一段内存空间,程序的依次动态执行,经理代码加载 -> 执行 -> 执行完毕的完整过程!

线程(Thread):比进程更小的执行单元,每个进程可能有多条线程,线程需要放在一个进程中才能执行! 线程是由程序负责管理的!!!而进程则是由系统进行调度的!!!

多线程概念(Multithreading):并行地执行多条指令,将CPU的时间片按照调度算法,分配给各个线程,实际上是分时执行的,只是这个切换的时间很短,用户感觉是同时而已!

举个简单的例子: 你挂着QQ,突然想去听歌,你需要把QQ关掉,然后再去启动XX播放器吗?答案是否定的,我们直接打开播放器 放歌就好,QQ还在运行着,是吧!这就是简单的多线程~在实际开发中,也有这样的例子,比如应用正在运行, 发现新版本了,想后台更新,这个时候一般我们会开辟出一条后台线程,用于下载新版本的apk,但是这个时候 我们还可以使用应用中的其他功能!这就是多线程的使用例子~

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 对象传进来即可~

2.AsyncTask全解析:

1)为什么要用AsyncTask?

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

2)AsyncTask的基本结构:

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

构建AsyncTask子类的参数:

注:

相关方法与执行流程:

注意事项:

3.AsyncTask使用示例:

因为我们还没学到Android网络那块,这里照顾下各位初学者,这里用延时 线程来模拟文件下载的过程~后面讲到网络那里再给大家写几个例子~

实现效果图:

布局文件:activity.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=".MyActivity">
    <TextView
        android:id="@+id/txttitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <!--设置一个进度条,并且设置为水平方向-->
    <ProgressBar
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/pgbar"
        style="?android:attr/progressBarStyleHorizontal"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/btnupdate"
        android:text="更新progressBar"/>
</LinearLayout> 

定义一个延时操作,用于模拟下载:

public class DelayOperator {
    //延时操作,用来模拟下载
    public void delay()
    {
        try {
            Thread.sleep(1000);
        }catch (InterruptedException e){
            e.printStackTrace();;
        }
    }
}

自定义AsyncTask:

public class MyAsyncTask extends AsyncTask<Integer,Integer,String>
{
    private TextView txt;
    private ProgressBar pgbar;  

    public MyAsyncTask(TextView txt,ProgressBar pgbar)
    {
        super();
        this.txt = txt;
        this.pgbar = pgbar;
    }  

    //该方法不运行在UI线程中,主要用于异步操作,通过调用publishProgress()方法
    //触发onProgressUpdate对UI进行操作
    @Override
    protected String doInBackground(Integer... params) {
        DelayOperator dop = new DelayOperator();
        int i = 0;
        for (i = 10;i <= 100;i+=10)
        {
            dop.delay();
            publishProgress(i);
        }
        return  i + params[0].intValue() + "";
    }  

    //该方法运行在UI线程中,可对UI控件进行设置
    @Override
    protected void onPreExecute() {
        txt.setText("开始执行异步线程~");
    }  

    //在doBackground方法中,每次调用publishProgress方法都会触发该方法
    //运行在UI线程中,可对UI控件进行操作  

    @Override
    protected void onProgressUpdate(Integer... values) {
        int value = values[0];
        pgbar.setProgress(value);
    }
}

MainActivity.java:

public class MyActivity extends ActionBarActivity {  

    private TextView txttitle;
    private ProgressBar pgbar;
    private Button btnupdate;  

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        txttitle = (TextView)findViewById(R.id.txttitle);
        pgbar = (ProgressBar)findViewById(R.id.pgbar);
        btnupdate = (Button)findViewById(R.id.btnupdate);
        btnupdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MyAsyncTask myTask = new MyAsyncTask(txttitle,pgbar);
                myTask.execute(1000);
            }
        });
    }
} 

好的,本节一开始给大家普及了下应用程序,进程,线程,多线程,异步,同步的概念;接着又讲解 了下Android中为何要引入异步操作,然后介绍了下AsyncTask的用法,当然上面也说了,异步操作在网络 操作用的较多,后面在讲解网络操作时会用到这个AsyncTask~

时间: 2025-01-07 15:43:25

事件处理机制之AnsyncTask异步任务的相关文章

【Nginx-反向代理服务器】基础知识(一)之事件处理机制

反向代理服务器: 反向代理(ReverseProxy)方式是在服务器端接受客户端的请求,然后把请求分发给具体的服务器进行处理,然后再将服务器的响应结果反馈给客户端. 正向代理服务器与反向代理服务器的区别: 正向代理: 用户A主动访问服务器B,但是用户A的所有请求都由代理服务器Z来处理,也就是在用户A访问服务器B时,会通过代理服务器Z 反向代理: 反向代理正好与正向代理相反,用户A始终认为它访问的是原始服务器B而不是代理服务器Z,但实用际上反向代理服务器接受用户A的应答(即用户A访问的是代理服务器

C#委托及事件处理机制浅析

事件可以理解为某个对象所发出的消息,以通知特定动作(行为)的发生或状态的改变.行为的发生可能是来自用户交互,如鼠标点击:也可能源自其它的程序逻辑.在这里,触发事件的对象被称为事件(消息)发出者(sender),捕获和响应事件的对象被称作事件接收者. 在事件(消息)通讯中,负责事件发起的类对象并不知道哪个对象或方法会接收和处理(handle)这一事件.这就需要一个中介者(类似指针处理的方式),在事件发起者与接收者之间建立关联.在.NET Framework中,定义了一个特殊的类型(delegate

QT开发(十二)——QT事件处理机制

QT开发(十二)--QT事件处理机制 一.QT事件简介 QT程序是事件驱动的, 程序的每个动作都是由内部某个事件所触发.QT事件的发生和处理成为程序运行的主线,存在于程序整个生命周期. 常见的QT事件类型如下: 键盘事件: 按键按下和松开 鼠标事件: 鼠标移动,鼠标按键的按下和松开 拖放事件: 用鼠标进行拖放 滚轮事件: 鼠标滚轮滚动 绘屏事件: 重绘屏幕的某些部分 定时事件: 定时器到时 焦点事件: 键盘焦点移动 进入和离开事件: 鼠标移入widget之内,或是移出 移动事件: widget的

《转之微信移动团队微信公众号》iOS 事件处理机制与图像渲染过程

致歉声明: Peter在开发公众号功能时触发了一个bug,导致群发错误.对此我们深表歉意,并果断开除了Peter.以下交回给正文时间: iOS 事件处理机制与图像渲染过程 iOS RunLoop都干了什么 iOS 为什么必须在主线程中操作UI 事件响应 CALayer CADisplayLink 和 NSTimer iOS 渲染过程 渲染时机 CPU 和 GPU渲染 Core Animation Facebook Pop介绍 AsyncDisplay介绍 参考文章 iOS RunLoop都干了什

iOS 事件处理机制与图像渲染过程

iOS 事件处理机制与图像渲染过程 iOS RunLoop都干了什么 iOS 为什么必须在主线程中操作UI 事件响应 CALayer CADisplayLink 和 NSTimer iOS 渲染过程 渲染时机 CPU 和 GPU渲染 Core Animation Facebook Pop介绍 AsyncDisplay介绍 参考文章 iOS RunLoop都干了什么 RunLoop是一个接收处理异步消息事件的循环,一个循环中:等待事件发生,然后将这个事件送到能处理它的地方. 如图1-1所示,描述了

JavaScript中事件处理机制

JavaScript中事件处理机制 JavaScript中代码的处理方式:单线程 + 事件队列(callback queue) :如果是纯单线程的话,js代码在执行的时候遇到耗时的操作,代码就会发生阻塞:利用事件队列的方式,代码在执行的时候会将回调函数放在事件队列中(callback queue),等主线程的任务执行完毕之后,执行event loop机制的线程会将满足执行条件的任务取出来(注意需要满足的两个前提条件:一:主线程的任务已经执行完毕:二:事件队列中的任务满足触发条件),放入主线程中进

nagios 事件处理机制

接到zz的任务,实现自动化处理nagios某项报警 脑海里有个印象,这个功能之前线下做过实验 一.首先必须查看下nagios的官方文档,确认可行,以下是笔者整理的一些自认为有用的信息 1)了解命令的定义方法Writing Event Handler CommandsEvent handler commands will likely be shell or perl scripts, but they can be any type of executable that can run from

Android基础入门教程——3.2 基于回调的事件处理机制

Android基础入门教程--3.2 基于回调的事件处理机制 标签(空格分隔): Android基础入门教程 本节引言 在3.1中我们对Android中的一个事件处理机制--基于监听的事件处理机制进行了学习,简单的说就是 为我们的事件源(组件)添加一个监听器,然后当用户触发了事件后,交给监听器去处理,根据不同的事件 执行不同的操作;那么基于回调的事件处理机制又是什么样的原理呢?好吧,还有一个问题:你知道 什么是方法回调吗?知道吗?相信很多朋友都是了解,但又说不出来吧!好了,带着这些疑问我们 对a

android开发详解(六)--------------事件处理机制

1.工程目录 2.FireEvent.java package com.example.fireeevent; import java.util.EventObject; //着火事件类,绑定事件源 public class FireEvent extends EventObject { private Object eventSource; public FireEvent(Object source) { super(source); // TODO Auto-generated const