现在的位置: 首页 > 综合 > 正文

53_进度条组件:ProgressBar、异步处理工具类:AsyncTask

2013年11月08日 ⁄ 综合 ⁄ 共 6867字 ⁄ 字号 评论关闭

一、进度条组件ProgressBar

  与ProgressDialog组件类似,ProgressBar的主要功能是用于显示操作进度,但是ProgressDialog组件是在运行时通过Activity程序生成的,而ProgressBar组件是直接在Layout布局中添加的,ProgressBar类是View类的直接子类。

  下面让我们通过一个实例来看一下进度条组件的使用:本程序定义了5个进度条组件和一个按钮组件,每种进度条都有不同的显示风格,并且设置了不同的当前进度,但是都默认为隐藏状态,而当单击按钮时,会将所有的组件设置为显示状态并开始进行进度的增长。程序通过一个线程启动所有的进度条组件进行显示,由于进度条要和主线程保持一致,所以程序使用一个Handler对象进行处理,此时的主线程和子线程共用了同一个Handler对象,这样在子线程中就可以对主线程的组件进行状态刷新的操作,若传递的消息类型为CONTINUE,则表示进行进度值的增长操作;如果传递的消息类型为STOP,则表示进度停止增长,并将所有的进度条设置为不可见状态。程序运行效果如下:

实现过程:

1. 编写布局管理器

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout  
    xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"   
    android:orientation="vertical">  
	<ProgressBar 
	    android:id="@+id/probar_1"
	    style="?android:attr/progressBarStyle"
	    android:visibility="gone"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"/>
	<ProgressBar 
	    android:id="@+id/probar_2"
	    style="?android:attr/progressBarStyleHorizontal"
	    android:visibility="gone"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"/>
	<ProgressBar 
	    android:id="@+id/probar_3"
	    style="?android:attr/progressBarStyleHorizontal"
	    android:visibility="gone"
	    android:max="120"
	    android:progress="0"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"/>
	<ProgressBar 
	    android:id="@+id/probar_4"
	    style="?android:attr/progressBarStyleLarge"
	    android:visibility="gone"
	    android:max="120"
	    android:progress="30"
	    android:secondaryProgress="50"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"/>
	<ProgressBar 
	    android:id="@+id/probar_5"
	    style="?android:attr/progressBarStyleSmall"
	    android:visibility="gone"
	    android:max="120"
	    android:progress="50"
	    android:secondaryProgress="70"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"/>
	<Button
	    android:id="@+id/button"
	    android:text="显示进度条"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"/>
</LinearLayout>

2. 编写MainActivity程序

package org.lion.messagetest;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;

public class MainActivity extends Activity {
	private ProgressBar probar_1, probar_2, probar_3, probar_4, probar_5;
	private Button button;
	protected static final int STOP = 1;   //停止消息
	protected static final int CONTINUE= 2;   //继续消息
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);		
		
		probar_1 = (ProgressBar)findViewById(R.id.probar_1);
		probar_2 = (ProgressBar)findViewById(R.id.probar_2);
		probar_3 = (ProgressBar)findViewById(R.id.probar_3);
		probar_4 = (ProgressBar)findViewById(R.id.probar_4);
		probar_5 = (ProgressBar)findViewById(R.id.probar_5);
		button = (Button)findViewById(R.id.button);
		probar_1.setIndeterminate(false);   //设置为不确定模式
		probar_2.setIndeterminate(false);
		probar_3.setIndeterminate(true);   //设置为确定模式
		probar_4.setIndeterminate(false);
		probar_5.setIndeterminate(false);
		button.setOnClickListener(new OnClickListenerImpl());
	}
	private class OnClickListenerImpl implements OnClickListener{
		@Override
		public void onClick(View v){
			probar_2.setSecondaryProgress(0);   //设置第二进度条
			probar_1.setVisibility(View.VISIBLE);   //设置组件为可见状态
			probar_2.setVisibility(View.VISIBLE);
			probar_3.setVisibility(View.VISIBLE);
			probar_4.setVisibility(View.VISIBLE);
			probar_5.setVisibility(View.VISIBLE);
			probar_1.setMax(150);
			probar_2.setMax(150);
			probar_1.setProgress(0);
			probar_2.setProgress(0);
			new Thread(new Runnable(){
				public void run(){   //线程主体
					int count = 0;   //用于保存当前进度值
					for(int i=0; i<10; i++){
						try{
							count = (i+1)*20;
							Thread.sleep(500);   //线程休眠0.5秒
							if(6 == i){
								Message msg = new Message();   //定义消息
								msg.what = STOP;   //消息代码
								MainActivity.this.massageHandler.sendMessage(msg);   //发送消息
								break;   //中断循环
							}else{
								Message msg = new Message();
								msg.arg1 = count;   //设置参数
								msg.what = CONTINUE;
								MainActivity.this.massageHandler.sendMessage(msg);
							}
						}catch(Exception e){
							e.printStackTrace();
						}
					}
				}
			}).start();   //启动线程
		}
	}
	
	//主线程和子线程共用此Handler对象
	private Handler massageHandler = new Handler(){
		@Override
		public void handleMessage(Message msg){
			switch(msg.what){
			case STOP:   //停止记录
				probar_1.setVisibility(View.GONE);   //设置组件为不可见状态
				probar_2.setVisibility(View.GONE);
				probar_3.setVisibility(View.GONE);
				probar_4.setVisibility(View.GONE);
				probar_5.setVisibility(View.GONE);
				Thread.currentThread().interrupt();
				break;
			case CONTINUE:   //组件增长
				probar_1.setProgress(msg.arg1);   //设置当前进度
				probar_2.setProgress(msg.arg1);
				probar_3.setProgress(msg.arg1);
				probar_4.setProgress(msg.arg1);
				probar_5.setProgress(msg.arg1);
				break;
			}
		}
	};
}

二、异步处理工具类:AsyncTask

  主线程和子线程之间的通信主要通过Handler完成,但是子线程无法直接对主线程的组件进行更新,为了解决这个问题,Android1.5后专门提供了一个android.os.AsyncTask类,可以通过此类完成非阻塞的操作。访类的功能与Handler类似,可以在后台操作,然后更新主线程的UI,但是它的使用方式比Handler容易得多。AsyncTask类直接继承于java.lang.Object类,它的定义如下:

android.os.AsyncTask<Params,Progress, Result>

AsyncTask类中通过泛型指定3个参数,这3个参数的作用如下:

(1)Params:启动时需要的参数类型,如每次操作的休眠时间为Integer

(2)Progress:后台执行任务的百分比,如进度条需要传递的是Integer

(3)Result:后台执行完毕之后返回的信息,如完成数据信息显示传递的是String

下面通过一个例子来演示AsyncTask类的使用方法,在该程序内部定义一个ChildTask类,此类继承自AsyncTask类,在ChildTask类中分别覆写onPostExecute()(任务完成后处理)、onProgressUpdate()(更新任务进度)、和doInBackground()(执行子任务)方法,主要的操作是在doInBackground()方法中,此方法中的参数(params)是通过child.execute(100)调用时传递进来的,表示每次休眠0.1秒。在子类ChildTask中对文本组件的更新操作是在onProgressUpdate()和onPostExecute()方法中完成的。doInBackground()方法只能完成子线程任务的操作,当执行publishProgress()方法后会将相应的更新状态传递给onProgressUpdate()方法,然后通过onProgressUpdate()方法进行主线程的更新操作。程序运行效果截图

实现过程:

1. 编写布局管理器

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout  
    xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"   
    android:orientation="vertical">  
	<ProgressBar 
	    android:id="@+id/probar_1"
	    style="?android:attr/progressBarStyleHorizontal"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"/>
	<TextView 
	    android:id="@+id/text"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"/>
</LinearLayout>

2. 编写Activity程序

package org.lion.messagetest;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ProgressBar;
import android.widget.TextView;

public class MainActivity extends Activity {
	private ProgressBar probar_1;
	private TextView text = null;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);		
		
		text = (TextView)findViewById(R.id.text);
		probar_1 = (ProgressBar)findViewById(R.id.probar_1);		
		ChildTask child = new ChildTask();
		child.execute(100);   //设置休眠时间
	}
	private class ChildTask extends AsyncTask<Integer, Integer, String>{
		@Override
		protected void onPostExecute(String result){//任务执行完毕后执行
			text.setText(result);
		}
		@Override
		protected void onProgressUpdate(Integer... progress){//每次更新后的值
			text.setText("当前进度:" + String.valueOf(progress[0]));
		}
		@Override
		protected String doInBackground(Integer... params){//处理后台任务
			for(int k=0; k<100; k++){
				probar_1.setProgress(k);
				this.publishProgress(k);  //向onProgressUpdate传递更新的内容
				try{
					Thread.sleep(params[0]);
				}catch(InterruptedException e){
					e.printStackTrace();
				}
			}
			return "任务执行完毕!";
		}		
	}
}

抱歉!评论已关闭.