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 }

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

原文地址:https://www.cnblogs.com/heyhhz/p/6135263.html