Android_AsyncTask异步任务机制

少年乘勇气,百战过乌孙。这篇文章主要讲述Android_AsyncTask异步任务机制相关的知识,希望能为你提供帮助。
今天我们学习了 AsyncTack, 这是一个异步任务。
那么这个异步任务可以干什么呢?
因为只有UI线程,即主线程可以对控件进行更新操作。好处是保证UI稳定性,避免多线程对UI同时操作。
同时要把耗时任务放在非主线程中执行,否则会造成阻塞,抛出无响应异常。
那么在android中实现异步任务机制有两种方式,Handler和AsyncTask。今天主要讲的是 asyncTack.
我们通过API 来学习下 整个 AsyncTack
一、结构
继承关系
【Android_AsyncTask异步任务机制】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" 2xmlns:tools="http://schemas.android.com/tools" 3android:layout_width="match_parent" 4android:layout_height="match_parent" 5android:paddingBottom="@dimen/activity_vertical_margin" 6android:paddingLeft="@dimen/activity_horizontal_margin" 7android:paddingRight="@dimen/activity_horizontal_margin" 8android:paddingTop="@dimen/activity_vertical_margin" 9tools:context="com.example.multithreadind01.MainActivity" > 10 11< TextView 12android:id="@+id/textView1" 13android:layout_width="wrap_content" 14android:layout_height="wrap_content" 15android:text="@string/hello_world" /> 16 17< Button 18android:id="@+id/button1" 19android:layout_width="wrap_content" 20android:layout_height="wrap_content" 21android:layout_alignParentRight="true" 22android:layout_alignTop="@+id/textView1" 23android:layout_marginRight="53dp" 24android:text="Button" /> 25 26< ListView 27android:id="@+id/listView1" 28android:layout_width="match_parent" 29android:layout_height="wrap_content" 30android:layout_below="@+id/button1" 31android:layout_marginTop="84dp" > 32< /ListView> 33 34< ProgressBar 35android:id="@+id/progressBar1" 36style="?android:attr/progressBarStyleHorizontal" 37android:layout_width="wrap_content" 38android:layout_height="wrap_content" 39android:layout_alignLeft="@+id/listView1" 40android:layout_alignRight="@+id/button1" 41android:layout_below="@+id/button1" 42android: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 { 4private String username; 5private String sex; 6public String getUsername() { 7return username; 8} 9public void setUsername(String username) { 10this.username = username; 11} 12public String getSex() { 13return sex; 14} 15public void setSex(String sex) { 16this.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 22private String fromDb_str1 = ""; 23private Button btn; 24private TextView tv; 25private ListView lv; 26private BaseAdapter adapter; 27private List< User> userList = new ArrayList< User> (); 28 29@Override 30protected void onCreate(Bundle savedInstanceState) { 31super.onCreate(savedInstanceState); 32setContentView(R.layout.activity_main); 33 34//模拟数据访问产生数据 35for (int i = 0; i < 5; i++) { 36User u = new User(); 37u.setUsername("小明"+i); 38u.setSex("女"+i); 39userList.add(u); 40} 41 42tv =(TextView)findViewById(R.id.textView1); 43btn =(Button)findViewById(R.id.button1); 44btn.setOnClickListener(new OnClickListener() { 45 46@Override 47public void onClick(View v) { 48MyTask mt = new MyTask(MainActivity.this); 49mt.execute(userList,adapter); //里面的参数是传给doInBackground 50/* 51Thread t1 = new Thread(new Runnable() { 52@Override 53public void run() { 54fromDb_str1 = "测试"; 55} 56}); 57t1.start(); 58tv.setText(fromDb_str1); 59*/ 60 61} 62}); 63adapter = new BaseAdapter(){ 64 65@Override 66public int getCount() { 67// TODO Auto-generated method stub 68return userList.size(); 69} 70 71@Override 72public View getView(int position, View convertView, ViewGroup parent) { 73LayoutInflater inflater = MainActivity.this.getLayoutInflater(); 74View view; 75if (convertView==null){ 76view = inflater.inflate(R.layout.item, null); 77} 78else{ 79view = convertView; 80} 81 82TextView tv_username = (TextView)view.findViewById(R.id.username); 83TextView tv_sex = (TextView)view.findViewById(R.id.sex); 84tv_username.setText(userList.get(position).getUsername()); 85tv_sex.setText(userList.get(position).getSex()); 86return view; 87} 88 89@Override 90public Object getItem(int position) { 91// TODO Auto-generated method stub 92return null; 93} 94 95@Override 96public long getItemId(int position) { 97// TODO Auto-generated method stub 98return 0; 99} 100}; 101lv = (ListView)findViewById(R.id.listView1); 102lv.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 14private BaseAdapter adapter; 15private List< User> userList; 16private MainActivity activity; 17public MyTask(MainActivity activity){ 18this.activity = activity; 19} 20 21//1.所有耗时的代码,写到这里来(数据库、蓝牙、网络服务) 22//2.绝对不能碰UI 23@Override 24protected Object doInBackground(Object... params) { 25 26userList = (List< User> ) params[0]; 27adapter = (BaseAdapter) params[1]; 28for (int i = 0; i < userList.size(); i++) { 29try { 30Thread.sleep(1000); 31} catch (InterruptedException e) { 32// TODO Auto-generated catch block 33e.printStackTrace(); 34} 35userList.get(i).setUsername("小红"+i); 36userList.get(i).setSex("男"+i); 37publishProgress(i); 38} 39 40 41//userlist,adapter 42 43//返回给前端 44return "天气:22度"; 45} 46 47//准备 48@Override 49protected void onPreExecute() { 50Toast.makeText(activity, "hello ,今晚约不约", Toast.LENGTH_SHORT).show(); 51 52} 53 54//做完后执行 55@Override 56protected void onPostExecute(Object result) { 57String r = result.toString(); 58TextView tv = (TextView)activity.findViewById(R.id.textView1); 59tv.setText("访问完成!"+r); 60 61} 62 63//分步完成 64@Override 65protected void onProgressUpdate(Object... values) { 66 67//0,1,2,3,4 68int bar = Integer.parseInt(values[0].toString()); 69bar = (bar+1)*20; 70ProgressBar progressBar = (ProgressBar)activity.findViewById(R.id.progressBar1); 71progressBar.setProgress(bar); 72adapter.notifyDataSetChanged(); 73} 74 75 }

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

文章图片

Android_AsyncTask异步任务机制

文章图片

Android_AsyncTask异步任务机制

文章图片

 

    推荐阅读