• 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 }

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

  • 相关阅读:
    创建窗口
    文件映射
    匿名管道
    MFC之进度条CProgressCtrl
    跨进程使用句柄和文件操作
    redis安装配置
    git全部操作
    idea中Entity实体中报错:cannot resolve column/table/
    Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezon
    sql操作
  • 原文地址:https://www.cnblogs.com/heyhhz/p/6135263.html
Copyright © 2020-2023  润新知