AsyncTask使用方法介绍

引言:当一个Android应用初次启动时,Android会自动创建一个主线程,这个主线程就是传说中的非常重要的UI线程,之所以说它重要,是因为它负责把事件分派给相应的控件(其中就包括屏幕绘图事件),同样,用户和控件的交互也是由它完成的。
但是因为所有的任务都是在同一线程中完成的,如果执行一些耗时的操作,如访问网络或查询数据库,不能及时的分发事件,导致阻塞用户界面的绘制。从用户的角度看,应用好像挂掉了,更糟的是,如果阻塞应用程序的时间过长(现在大概是5秒钟)Android会向用户提示一些信息,即 “应用程序没有响应”的对话框。
如何解决这个问题?
我们用的最多的办法就是Handler + Thread 的方式,即:

  1. 新开一个线程,在该线程中执行比较耗时的操作。
  2. 耗时操作完成后,用Handler向UI线程发送消息,通知主线程更新UI。
    这种方式虽然简单,但是缺点也是显而易见的,比如代码相对臃肿,在多个任务同时执行时,不易对线程进行精确的控制;比如耗时的操作太多,那么我们需要开启太多的子线程,这就会给系统带来巨大的负担,随之也会带来性能方面的问题。
    那么有没有其他的方式可供选择呢?
    有!它就是AsyncTask
    AsyncTask的使用方法:
  3. AsyncTask对线程间的通讯做了包装,使后台线程和UI线程可以简易通讯:后台线程执行异步任务,将result告知UI线程。
  4. 使用方法:定义一个继承自AsyncTask<Params,Progress,Result>的方法,把比较耗时的操作放在doInBackground中完成,onPostExecute方法中可以完成对UI的更新。
    下面对AsyncTask<Params,Progress,Result>使用的参数及需要实现的方法做下详细的说明。
    AsyncTask<Params,Progress,Result>
    Params:输入参数。对应的是调用自定义的AsyncTask的类中excute()方法中传递的参数。如果不需要传递参数,则直接设为Void即可。
    Progress:子线程执行的百分比。用于更新进度条。
    Result:返回值类型。和doInBackground()方法的返回值类型保持一致。
    onPreExecute():
    A. 无返回值类型,不传参数。
    B. 在执行实际的后台操作前,被UI 线程调用,无需我们手动调用。
    C. 作用:可以在该方法中做一些准备工作,如一些控件的实例化等。
    D. AsyncTask类中该方法是空方法,可以不用实现。
    E. 需要强调的是,该方法在UI线程中被调用。
    doInBackground(Params… params):
    A. 返回值类型和Result保持一致。参数:若无,就传递Void;若有,就用Params
    B. 在执行实际的后台操作,被后台线程调用,无需我们手动调用。
    C. 作用:AsyncTask的主力军,所有耗时的操作在此方法中完成。
    D. AsyncTask类中该方法是一个抽象方法,我们继承AsyncTask时必须覆写此方法。
    E. 需要强调的是,该方法在后台线程中被调用。
    publishProgress(Params… params):
    A.该方法无需覆写,直接调用即可。
    B.在执行此方法的时候会直接调用onProgressUpdate(Params… values)
    C.作用:用来调用onProgressUpdate方法,更新进度条。
    D.该方法一般在doInBackground方法中调用。
    onProgressUpdate(Params… values):
    A. 无返回值类型。参数:若无就传递Void;若有,就可用values
    B. 在publishProgress执行时被调用,无需我们手动调用。
    C. 作用:更新进度条
    onPostExecute(Result result) :
    A. 无返回值类型。参数:和Result保持一致。
    B. 当后台操作结束时,此方法将会被调用,doInBackground的计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。
    execute(Params… params):
    A.执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。
    对于上面的说明,还需要注意的是:
  5. AsyncTask<Params,Progress,Result>,doInBackground(Params… params),execute(Params… params)这但三者的Params 类型必须是一致的。
  6. doInBackground(Params… params)的返回值要作为onPostExecute(Result result)的实参使用的,所以二者的类型也是必须一致的。
    另外,在使用的时候,有几点需要格外注意:
    1.异步任务的实例必须在UI线程中创建。
    2.execute(Params… params)方法必须在UI线程中调用。
    3.不要手动调用onPreExecute(),doInBackground(Params… params),onProgressUpdate(Progress… values),onPostExecute(Result result)这几个方法。
    4.不能在doInBackground(Params… params)中更改UI组件的信息。
    5.一个任务实例只能执行一次,如果执行第二次将会抛出异常。
    示例代码:

```c

```java
package com.example.asynctask;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
   TextView textView;
   Button button1,button2;
   ProgressBar pb;
   myTask mt;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		button1 = (Button)findViewById(R.id.button1);
		button2 = (Button)findViewById(R.id.button2);
		textView = (TextView)findViewById(R.id.textView1);
		pb = (ProgressBar)findViewById(R.id.progressBar1);
		mt = new myTask(MainActivity.this,pb,textView);
		button1.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				mt.execute(100);//执行异步任务
			}
		});
		button2.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				mt.cancel(true);//取消异步任务
			}
		});
	}
	

	private class myTask extends AsyncTask<Integer,Integer,String>{
	    private Context mContext = null;
	    private ProgressBar mProgressBar=null;
	    private TextView mTextView=null;
	    public myTask(Context context,ProgressBar pb,TextView tv){
	        this.mContext = context;
	        this.mProgressBar = pb;
	        this.mTextView = tv;
	    }
		
		@Override
		protected void onPreExecute() {
			Toast.makeText(mContext, "开始下载", Toast.LENGTH_SHORT).show();
		}
		
	    @Override
	    protected String doInBackground(Integer... params) {
	        for(int i = 0;i <= 100; i++){
	            publishProgress(i);
	            try {
	                Thread.sleep(params[0]);
	            } catch (InterruptedException e) {
	                // TODO Auto-generated catch block
	                e.printStackTrace();
	            }
	        }
	        return "下载完毕";
	    }
	    @Override
	    protected void onProgressUpdate(Integer... values) {
	        textView.setText("" + values[0] + "%");
	    	mProgressBar.setProgress(values[0]);
	    }
	    
	    @Override
	    protected void onPostExecute(String result) {
	    	Toast.makeText(mContext, result, Toast.LENGTH_LONG).show();
	    }
	}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.asynctask.MainActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:layout_marginLeft="40dp"
        android:text="start" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/button1"
        android:layout_alignBottom="@+id/button1"
        android:layout_marginLeft="39dp"
        android:layout_toRightOf="@+id/button1"
        android:text="stop" />

    <ProgressBar
        android:id="@+id/progressBar1"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="200dp"
        android:layout_height="50dp"
        android:layout_alignLeft="@+id/button1"
        android:layout_alignParentTop="true"
        android:layout_marginTop="66dp" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/progressBar1"
        android:layout_alignTop="@+id/progressBar1"
        android:text="TextView" />

</RelativeLayout>



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值