Android更新界面之一——AsyncTask

一、注意:要看懂这篇文章,前提是你已经会java可变参数和java泛型相关知识, 可变参数知识点请参考我写的博客java可变参数.
二、Android中Activity运行在主进程的主线程中,由于该线程主要用界面与用户交互,所以其线程又叫UI线程,要想更新UI(UI就是界面的意思),只能在UI线程中
,一般办法去新开辟的线程中是无法更新UI的,当在UI线程中更新UI,但是使用时间操作5秒钟又要报错,为了解决更新UI而时间很长所情况,Android提供了以下几个办法,Handler更新UI;广播中更新UI;Activity runOnUiThread(Runnable run);View:post();View:postDelayed();AsyncTask。其中Handler和AsyncTask是用得最多的方式,本篇讲解AsyncTask的使用。
三、AsyncTask是抽象类,继承该类要使用泛型AsyncTask<Params, Progress, Result>,其中Params, Progress, Result是任意类名
* 泛型Params对应execute函数中的可变参数类型
* 泛型Progress对应函数publishProgress中的参数和onProgressUpdate函数中的可变参数类型
* 泛型Result对应doInBackground函数的返回值和onPostExecute函数的参数
(函数execute、函数publishProgress、函数onProgressUpdate、函数doInBackground和函数onPostExecute都是AsyncTask类的函数)
eg:
public class MyAsyncTask extends AsyncTask<Short, Integer, String>
{
 ........
}
* 泛型Short对应(1)execute函数中的可变参数类型
* 泛型Integer对应函数publishProgress中的参数和onProgressUpdate函数中的可变参数类型
* 泛型String对应doInBackground函数的返回值和onPostExecute函数的参数
四、
AsyncTask类有以下方法,其中doInBackground方法是抽象方法。
(1)public final AsyncTask<Params, Progress, Result> execute(Params... params):
该方法由我们自己在UI线程中调用,使用是启动AsyncTask,是该类使用的入口,方法调用后,后台会立刻回调用onPreExecute方法,注意只能在UI线程中调用execute方法。参数params会传到doInBackground方法中作为参数值
(2)protected void onPreExecute():
该方法在UI调用execute方法启动AsyncTask后立刻被回调,主要用于初始化,该方法是在UI线程中执行的,所以执行时间不能操过5秒,onPreExecute方法执行完后,后台立刻自动回调用doInBackground方法
(3)protected abstract Result doInBackground (Params... params):
该方法是在onPreExecute()执行结束后立刻被回调,该方法是在后台新开辟子线程中执行的,所以可以做长时间的工作,如网络下载。参数params接收到的值就是UI线程调用execute(Params... params)方法时传的参数值。doInBackground方法执行完后,会自动调用
onPostExecute方法,doInBackground的返回值会作为onPostExecute方法参数值
(4)protected final void publishProgress (Progress... values):
该方法由我们自已手动调用,一般是在子线程中执行的doInBackground方法中调用publishProgress方法,该方法调用后,后台会在UI线程中回调onProgressUpdate (Progress... values)方法,并且publishProgress中参数值会传到onProgressUpdate方法中使用参数值,实际开发中values用于表示doInBackground方法执行的进度
(5)protected void onProgressUpdate (Progress... values)
该方法在publishProgress方法执行后,自动被回调用,该方法在UI线程中执行。一般用于更新UI,显示函数doInBackground执行的进度
(6)protected void onPostExecute (Result result)
该方法是当doInBackground方法执行完后,在UI线程中自动调用,参数接收的值是doInBackground方法的反回值
(7)public final boolean cancel (boolean mayInterruptIfRunning)
该方法由我们自己调用,该方法传参数值true调用后,再去调用isCancelled方法会得到返回值true,cancel方法与isCancelled方法配合使用,可以中断AsyncTask
(8)public final boolean isCancelled ():
一般在publishProgress函数中手动调用,用于判断AsyncTask是否被取消了。

五、举例=========================================
(1)新建项目
(2)布局文件main.xml内容为
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <TextView
    android:id="@+id/MyTextView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="show"
    android:textSize="40sp"
    />
    <Button
    android:id="@+id/begin"  
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="开始"
    />
    <Button 
    android:id="@+id/end"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="结束"
    />
</LinearLayout>

(3)Activity子类代码为

package com.fs.activity;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {
 private TextView textView;
 private Button begin, end;
 private AsyncTask<Short, Integer, String> task = null;
 private void init() {
  this.textView = (TextView) this.findViewById(R.id.MyTextView);
  this.begin = (Button) this.findViewById(R.id.begin);
  this.end = (Button) this.findViewById(R.id.end);
  this.begin.setOnClickListener(this);
  this.end.setOnClickListener(this);
 }
 @Override
 public void onClick(View v) {
  if (v == this.begin) {/*1  点始开始按钮**/
   Short param1 = 0;
   Short param2 = 10;
   /*开启AsyncTask,该代码运行后,在UI线程中,MyAsyncTask类中的onPreExecute函数会被自动回调用*/
   this.task = new MyAsyncTask().execute(param1, param2); /*2*/
  } else if (v == this.end) {
   
  }
 }
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.main);
  this.init();
 }
 /***
  * 泛型Short对应(1)execute函数中的可变参数类型
  * 泛型Integer对应函数publishProgress中的参数和onProgressUpdate函数中的可变参数类型
  * 泛型String对应doInBackground函数的返回值和onPostExecute函数的参数
  * @author Administrator
  *
  */
 public class MyAsyncTask extends AsyncTask<Short, Integer, String> {
  /**该函数执行完后,系统会自动开辟子线程,并在子程中自动回调用doInBackground函数**/
  @Override
  protected void onPreExecute() {/*3*/
   Toast.makeText(MainActivity.this, "开始更新界面", Toast.LENGTH_LONG).show();
  }
  /**(1)当onPreExecute函数执行完后,立刻创建子线程,并回调doInBackground函数,参数params接收到的值就是前面代码this.task = new MyAsyncTask().execute(param1,    param2); 中param1,和param2,该函数可以做长时间的事情
   * (2)当onPreExecute函数全部执行完成后,UI线程中会自动回调onPostExecute函数,并且doInBackground函数的返回值会成为 onPostExecute函数的参数值。
   * (3)由于doInBackground函数是在子线程(不是UI线程)中执行的,所以该函数不能更新UI
   * */
  @Override
  protected String doInBackground(Short... params) {/*4*/
   Short param1 = params[0];
   Short param2 = params[1];
   for (int i = param1; i < param2; i++) {
    /*publishProgress调用后,onProgressUpdate函数在UI线程中被自动回调,并且onProgressUpdate函数接收到的参数就是param2-i但由于onProgressUpdate函数的执行是在UI线程中执行的,所以不会阻赛doInBackground函数的继续执行。*/
    this.publishProgress(param2 - i);
    try {
     Thread.sleep(1000);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
   return "更新完毕了!";
  }
  @Override
  protected void onProgressUpdate(Integer... values) {
   MainActivity.this.textView.setText("还差" + values[0] + "秒");
  }
  /**
   * (1)doInBackground函数执行完成后,onPostExecute函数会被自动回调用
   * (2)onPostExecute函数是在UI线程中执行的,所以可以更新UI
   * (3)onPostExecute函数的参数值是doInBackground线程的返回值
   */
  @Override
  protected void onPostExecute(String result) {/*5*/
   MainActivity.this.textView.setText(result);
  }
 }
}

上面项目的效果
(1)项目运行后界面显示为
(2)点击开始按钮后界面显示为,可以看到界面上方的文字在变化即:还差10秒,还差9秒,还差8秒......还差1秒,更新完毕了;

 注意事项:

 同一个AsyncTask类的对象只能被启动一次,就像同一个Thread类对象只能调用一次start函数启动一次一样

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值