Android_AsyncTask异步任务机制

今天我们学习了 AsyncTack, 这是一个异步任务。

那么这个异步任务可以干什么呢?

  因为只有UI线程,即主线程可以对控件进行更新操作。好处是保证UI稳定性,避免多线程对UI同时操作。

  同时要把耗时任务放在非主线程中执行,否则会造成阻塞,抛出无响应异常。

那么在Android中实现异步任务机制有两种方式,Handler和AsyncTask。今天主要讲的是 asyncTack.

  我们通过API 来学习下 整个 AsyncTack

一、结构

  继承关系

     public abstract class AsyncTask extends Object

  java.lang.Object

    android.os.AsyncTask <params,Progress,Result>

二、类概述

  AsyncTask  能够适当的,简单的用于 UI 线程。这个类不需要操作线程(Thread)就可以完成后台操作将结果返回 UI

  异步任务的定义是一个在后台线程上运行,其结果是在UI线程上发布的计算。

异步任务被定义成

三种泛型类型:

Params:启动任务执行的输入参数。

Progress:后台人数执行的百分比

Result:后台计算的结果类型

注:在一个异步任务中,不是所有的类型总被用。假如一个类型不被使用,可以简单地使用void 类型。

四个步骤:

1.onPreExecute():在UI线程上调用任务后立即执行。这步通常被用于设置任务,例如在用户界面显示一个进度条。

2.doInBackground(Params...):后台线程执行 onPreExecute()完成立即调用,这步被用于执行较长时间的后台计算。异步任务的参数也被传到这步。计算的结果必须在这步返回,将返回到上一步。在执行过程中可以调用 publishProgress(Progress...)来更新人无语的进度。

3.onProcessProgress():一次呼叫 publishProgress(Progress...)后调用UI线程。执行时间是不确定的。这个方法用于当后台计算还在进行时在用户界面显示进度。例如:这个方法可以被用于一个进度条动画或在文本域显示记录。

4.onPostExecute(Resule):当后台计算结束时,调用 UI线程。后台计算结果作为一个参数传递到这步。

接下来我们用一个栗子看看这个 AsyncTask 到底能做什么。

这是我们的xml 布局文件

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:paddingBottom="@dimen/activity_vertical_margin"
 6     android:paddingLeft="@dimen/activity_horizontal_margin"
 7     android:paddingRight="@dimen/activity_horizontal_margin"
 8     android:paddingTop="@dimen/activity_vertical_margin"
 9     tools:context="com.example.multithreadind01.MainActivity" >
10
11     <TextView
12         android:id="@+id/textView1"
13         android:layout_width="wrap_content"
14         android:layout_height="wrap_content"
15         android:text="@string/hello_world" />
16
17     <Button
18         android:id="@+id/button1"
19         android:layout_width="wrap_content"
20         android:layout_height="wrap_content"
21         android:layout_alignParentRight="true"
22         android:layout_alignTop="@+id/textView1"
23         android:layout_marginRight="53dp"
24         android:text="Button" />
25
26     <ListView
27         android:id="@+id/listView1"
28         android:layout_width="match_parent"
29         android:layout_height="wrap_content"
30         android:layout_below="@+id/button1"
31         android:layout_marginTop="84dp" >
32     </ListView>
33
34     <ProgressBar
35         android:id="@+id/progressBar1"
36         style="?android:attr/progressBarStyleHorizontal"
37         android:layout_width="wrap_content"
38         android:layout_height="wrap_content"
39         android:layout_alignLeft="@+id/listView1"
40         android:layout_alignRight="@+id/button1"
41         android:layout_below="@+id/button1"
42         android:layout_marginTop="28dp" />
43
44 </RelativeLayout>

这是我们listView 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="horizontal" >
    <TextView
        android:id="@+id/username"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:textSize="45dp"
        />

    <TextView
        android:id="@+id/sex"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:textSize="45dp"
        />
</LinearLayout>

这是我们的 user.class

 1 package com.example.multithreadind01;
 2
 3 public class User {
 4     private String username;
 5     private String sex;
 6     public String getUsername() {
 7         return username;
 8     }
 9     public void setUsername(String username) {
10         this.username = username;
11     }
12     public String getSex() {
13         return sex;
14     }
15     public void setSex(String sex) {
16         this.sex = sex;
17     }
18
19 }

MainActivity.class

  1 package com.example.multithreadind01;
  2
  3 import java.util.ArrayList;
  4 import java.util.List;
  5
  6 import android.app.Activity;
  7 import android.os.Bundle;
  8 import android.view.LayoutInflater;
  9 import android.view.Menu;
 10 import android.view.MenuItem;
 11 import android.view.View;
 12 import android.view.View.OnClickListener;
 13 import android.view.ViewGroup;
 14 import android.widget.BaseAdapter;
 15 import android.widget.Button;
 16 import android.widget.ListView;
 17 import android.widget.TextView;
 18
 19
 20 public class MainActivity extends Activity {
 21
 22     private String fromDb_str1 = "";
 23     private Button btn;
 24     private TextView tv;
 25     private ListView lv;
 26     private BaseAdapter adapter;
 27     private List<User> userList = new ArrayList<User>();
 28
 29     @Override
 30     protected void onCreate(Bundle savedInstanceState) {
 31         super.onCreate(savedInstanceState);
 32         setContentView(R.layout.activity_main);
 33
 34         //模拟数据访问产生数据
 35         for (int i = 0; i < 5; i++) {
 36             User u = new User();
 37             u.setUsername("小明"+i);
 38             u.setSex("女"+i);
 39             userList.add(u);
 40         }
 41
 42         tv =(TextView)findViewById(R.id.textView1);
 43         btn =(Button)findViewById(R.id.button1);
 44         btn.setOnClickListener(new OnClickListener() {
 45
 46             @Override
 47             public void onClick(View v) {
 48                 MyTask mt = new MyTask(MainActivity.this);
 49                 mt.execute(userList,adapter);//里面的参数是传给doInBackground
 50                 /*
 51                 Thread t1 = new Thread(new Runnable() {
 52                     @Override
 53                     public void run() {
 54                         fromDb_str1 = "测试";
 55                     }
 56                 });
 57                 t1.start();
 58                 tv.setText(fromDb_str1);
 59                 */
 60
 61             }
 62         });
 63         adapter = new BaseAdapter(){
 64
 65             @Override
 66             public int getCount() {
 67                 // TODO Auto-generated method stub
 68                 return userList.size();
 69             }
 70
 71             @Override
 72             public View getView(int position, View convertView, ViewGroup parent) {
 73                 LayoutInflater inflater = MainActivity.this.getLayoutInflater();
 74                 View view;
 75                 if (convertView==null){
 76                     view = inflater.inflate(R.layout.item, null);
 77                 }
 78                 else{
 79                     view = convertView;
 80                 }
 81
 82                 TextView tv_username = (TextView)view.findViewById(R.id.username);
 83                 TextView tv_sex = (TextView)view.findViewById(R.id.sex);
 84                 tv_username.setText(userList.get(position).getUsername());
 85                 tv_sex.setText(userList.get(position).getSex());
 86                 return view;
 87             }
 88
 89             @Override
 90             public Object getItem(int position) {
 91                 // TODO Auto-generated method stub
 92                 return null;
 93             }
 94
 95             @Override
 96             public long getItemId(int position) {
 97                 // TODO Auto-generated method stub
 98                 return 0;
 99             }
100         };
101         lv = (ListView)findViewById(R.id.listView1);
102         lv.setAdapter(adapter);
103     }
104 }

最后是我们异步类 MyTask.class

 1 package com.example.multithreadind01;
 2
 3 import java.util.List;
 4
 5 import android.os.AsyncTask;
 6 import android.view.View;
 7 import android.widget.BaseAdapter;
 8 import android.widget.ProgressBar;
 9 import android.widget.TextView;
10 import android.widget.Toast;
11
12 public class MyTask extends AsyncTask {
13
14     private BaseAdapter adapter;
15     private List<User> userList;
16     private MainActivity activity;
17     public MyTask(MainActivity activity){
18         this.activity = activity;
19     }
20
21     //1.所有耗时的代码,写到这里来(数据库、蓝牙、网络服务)
22     //2.绝对不能碰UI
23     @Override
24     protected Object doInBackground(Object... params) {
25
26         userList = (List<User>) params[0];
27         adapter = (BaseAdapter) params[1];
28         for (int i = 0; i < userList.size(); i++) {
29             try {
30                 Thread.sleep(1000);
31             } catch (InterruptedException e) {
32                 // TODO Auto-generated catch block
33                 e.printStackTrace();
34             }
35             userList.get(i).setUsername("小红"+i);
36             userList.get(i).setSex("男"+i);
37             publishProgress(i);
38         }
39
40
41         //userlist,adapter
42
43         //返回给前端
44         return "天气:22度";
45     }
46
47     //准备
48     @Override
49     protected void onPreExecute() {
50         Toast.makeText(activity, "hello ,今晚约不约", Toast.LENGTH_SHORT).show();
51
52     }
53
54     //做完后执行
55     @Override
56     protected void onPostExecute(Object result) {
57         String r = result.toString();
58         TextView tv = (TextView)activity.findViewById(R.id.textView1);
59         tv.setText("访问完成!"+r);
60
61     }
62
63     //分步完成
64     @Override
65     protected void onProgressUpdate(Object... values) {
66
67         //0,1,2,3,4
68         int bar = Integer.parseInt(values[0].toString());
69         bar = (bar+1)*20;
70         ProgressBar progressBar = (ProgressBar)activity.findViewById(R.id.progressBar1);
71         progressBar.setProgress(bar);
72         adapter.notifyDataSetChanged();
73     }
74
75 }

以上案例使我们做到后台数据加载到前端的过程中,使用异步,不会出现所谓的“卡顿”。使得整个程序运行的效果是畅通的,用户体验性也提高。

时间: 2024-10-07 06:30:45

Android_AsyncTask异步任务机制的相关文章

Android Learning:多线程与异步消息处理机制

在最近学习Android项目源码的过程中,遇到了很多多线程以及异步消息处理的机制.由于之前对这块的知识只是浅尝辄止,并没有系统的理解.但是工程中反复出现让我意识到这个知识的重要性.所以我整理出这篇博客,主要介绍了线程和异步处理机制的意义和用法,目的在于帮助初学者能够加深对异步消息处理机制的理解,在实际Android工程中能够更多地使用AsyncTask工具类在子线程中进行UI更新. 一.Android当中的多线程[1] 在Android当中,当一个应用程序的组件启动的时候,并且没有其他的应用程序

Android异步消息处理机制(3)asyncTask基本使用

本文翻译自android官方文档,结合自己测试,整理如下. 概述 AsyncTask抽象类,翻译过来就是异步任务,能够合理并方便的使用UI线程.该类可以实现将后台操作结果显示在UI线程中,而不需要我们自己实现子线程或者handler(当然它内部也是借助这两者实现的). 虽然AsyncTask可以提供后台运行并将结果显示在UI上,但是理想情况应该是后台操作最多只能是几秒钟,若要执行长时间的操作强烈建议使用java中的Executor,ThreadPoolExecutor,FutureTask等.

Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38377229 ,本文出自[张鸿洋的博客] 很多人面试肯定都被问到过,请问Android中的Looper , Handler , Message有什么关系?本篇博客目的首先为大家从源码角度介绍3者关系,然后给出一个容易记忆的结论. 1. 概述 Handler . Looper .Message 这三者都与Android异步消息处理线程相关的概念.那么什么叫异步消息处理线程呢?异步

Android异步消息传递机制源码分析&amp;&amp;相关知识常被问的面试题

1.Android异步消息传递机制有以下两个方式:(异步消息传递来解决线程通信问题) handler 和 AsyncTask 2.handler官方解释的用途: 1).定时任务:通过handler.postDelay(Runnable r, time)来在指定时间执行msg. 2).线程间通信:在执行较为耗时操作的时候,在子线程中执行耗时任务,然后handler(主线程的)把执行的结果通过sendmessage的方式发送给UI线程去执行用于更新UI. 3.handler源码分析 一.在Activ

Linux内核中断引入用户空间(异步通知机制)【转】

转自:http://blog.csdn.net/kingdragonfly120/article/details/10858647 版权声明:本文为博主原创文章,未经博主允许不得转载. 当Linux内核空间发生中断后怎么使用户空间的应用程序运行相应的函数呢,当芯片有数据到来时内核会产生一个中断,但是怎样通知应用程序来取数据,以前这个问题一直困扰我很长时间,后来发现linux中有异步通知机制,在用户程序中用signal注册一个响应SIGIO信号的回调函数,然后在驱动程序中向该进程发出SIGIO信号

Android多线程——异步消息处理机制

Android中的异步消息处理机制主要由四个部分组成,Message.Handler.MessageQueueh和Looper.这里先简要介绍一下四个部分. 1.Message Message是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据,Message可以使用what.arg1和arg2字段来携带一些整形数据.使用obj来携带一个Object对象. 2.Handler Handler是处理者的意思,主要用于发送和处理消息.发送消息一般是使用Handler的sen

Android异步消息处理机制——handle与Looper,AsyncTask

Android线程间的通讯采用异步消息处理机制,主要由四部分组成,包括Message,Handler,MessageQueue和Looper. 一个线程只有一个Looper与Messagequeue,但可以有多个handler实例. 例:线程A发消息Message,线程B处理消息Message. 需要在线程B中新建一个Handler实例handler,在A线程中通过该handler发送消息到线程B中的Messagequeue中, 通过B中的Looper以及先进先出的原则取出该消息并处理消息,所以

【译】深入理解python3.4中Asyncio库与Node.js的异步IO机制

转载自http://xidui.github.io/2015/10/29/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3python3-4-Asyncio%E5%BA%93%E4%B8%8ENode-js%E7%9A%84%E5%BC%82%E6%AD%A5IO%E6%9C%BA%E5%88%B6/ 译者:xidui原文: http://sahandsaba.com/understanding-asyncio-node-js-python-3-4.html 译者前言 如

[Android] Android异步任务机制之AsycTask

在Android中实现异步任务机制有两种方式,Handler和AsyncTask. Handler已经在上一篇文章 异步消息处理机制(Handler . Looper .MessageQueue)源码解析 说过了. 本篇就说说AsyncTask的异步实现. 1.什么时候使用 AsnyncTask 在上一篇文章已经说了,主线程主要负责控制UI页面的显示.更新.交互等. 为了有更好的用户体验,UI线程中的操作要求越短越好. 我们把耗时的操作(例如网络请求.数据库操作.复杂计算)放到单独的子线程中操作