一、进度条组件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 "任务执行完毕!"; } } }