【Android】进度条与线程之间的消息处理

有点没想到的是,这样的一个小小的程序弄了很久才做完。

这个程序看起来很简单的,如下图:

一个进度条在不断地增加,累加到超过100%,隐藏载入进度条,并且文字改变成一个“倒数3秒”继续执行。

数完三秒之后则继续进行进度条的累加。

首先,由于标签文本是动态的,通过Java文件控制,在res\values\string.xml,仅仅需要把程序名称改成“进度条”,没有什么特别的:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">进度条</string>
    <string name="action_settings">Settings</string>

</resources>

之后,布局也没有什么特别的,思想如下图:

在res\layout\activity_main.xml中,修改成如下代码即可:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <ProgressBar
            android:id="@+id/ProgressBar1"
            style="@android:style/Widget.ProgressBar.Large"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
             android:id="@+id/TextView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>

    <ProgressBar
        android:id="@+id/ProgressBar2"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100" />

</LinearLayout>

其中,这里细长进度条ProgressBar2的style可能比较特别,但安卓是这样要求的没有办法,指定其最大值为100%。进度条1,看起来像是个不断旋转的载入图像,但其实也是进度条的一种,其没有最大值,也不能通过Java文件设置其当前进度,在MainActivity.Java中只能设定其显示与否。

这里为各个组件设置ID,同时使用了嵌套线性布局。

关键是MainActivity.java这个文件弄了我好久,代码如下:

package com.progressbar;

import java.util.Timer;
import java.util.TimerTask;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;

public class MainActivity extends Activity {
	private ProgressBar ProgressBar1;
	private ProgressBar ProgressBar2;
	private TextView TextView1;
	//定义一个消息处理器。
	private Handler handler;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//获取各个组件,没有什么特别的。
		ProgressBar1 = (ProgressBar) findViewById(R.id.ProgressBar1);
		ProgressBar2 = (ProgressBar) findViewById(R.id.ProgressBar2);
		TextView1 = (TextView) findViewById(R.id.TextView1);

		//设置一个每隔1000毫秒,也就是1秒就运行一次的定时器
		new Timer().schedule(new TimerTask() {
			int i = 0;//这里代表进度
			int j = 3;//这里代表进度达100%时的倒数

			@Override
			public void run() {
				Message msg = new Message();
				//这里的消息声明必须放在run()方法之中,否则程序,由于旧的消息不消亡会卡死
				//把Message的new方法,放在run()这里,定时器每一次重新执行,则会杀死旧信息,创建新的信息。
				if (i < 100) {
					msg.what = i;
					handler.sendMessage(msg);//将i存放到msg的what类成员中传给消息处理器
					i += Math.random() * 20;//i每次递增20*(0.xxx)的进度
				} else {
					if (j > 0) {
						msg.what = i;
						msg.arg1 = j;
						handler.sendMessage(msg);//将j放到msg的arg1类成员中传递给消息处理器
						j--;
					} else {//倒数完毕,重新开始
						i = 0;
						j = 3;
					}
				}
			}
		}, 0, 1000);

		//不停在接受定时器的消息,根据消息的参数,进行处理
		handler = new Handler(new Handler.Callback() {//这样写,就不弹出什么泄漏的警告了
			@Override
			public boolean handleMessage(Message msg) {
				if (msg.what < 100) {//如果消息的 what参数少于100,则设置进度条
					ProgressBar2.setProgress(msg.what);//设置细长进度条ProgressBar2的进度
					if (msg.what == 0) {//仅仅是在what参数等于0的时候,设置标签文本与进度条,不要每次读取进度都加载。
						TextView1.setText("正在运行中……");
						ProgressBar1.setVisibility(View.VISIBLE);
					}
				} else {
					if (msg.arg1 == 3) {
						ProgressBar1.setVisibility(View.GONE);
						ProgressBar2.setProgress(0);
					}
					TextView1.setText("运行完毕,等待" + msg.arg1 + "秒继续运行下一次的程序……");
				}
				return false;
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

可能有人不解,为何不直接在定时器中设置文本,还要非常复杂的样子整个消息处理器Handle,又要处理器的泄露问题。

我最初也不像这样整的,全因为定时器是一条新的线程,安卓不允许在别的线程中设置标签文本TextView1的值,如果你不是在Android进程中设置标签文本的,则会弹出一下的错误提示:

因此,必须利用安卓在线程中的消息传递,让处于安卓的Original Thread来设置标签文本的值,对进度条进行处理。就这个东西搞了我很久。

同时,这里的定时器的设置使用了Java中的匿名内部类,具体见《【Java】定时器、线程与匿名内部类》(点击打开链接)。这里不赘述了。

最后随便说一句,这里的标签文本可以设置其TextSize="24sp",默认的字体太小,不太好看。

时间: 2024-10-16 11:40:03

【Android】进度条与线程之间的消息处理的相关文章

android 进度条

在之前实现自定义进度条的时候,基本上都是使用ImageView来实现的,见  Android 用Animation-list实现逐帧动画,最近一段时间看到APP的进度条很多都是ProgressBar然后圆圈里面是一张图片,所以就查看了一下ProgressBar的使用. 1.动画实现 定义res/anim/loading.xml,例如: <?xml version="1.0" encoding="UTF-8"?> <animation-list

【Android进度条】三种方式实现自定义圆形进度条ProgressBar

一.通过动画实现 定义res/anim/loading.xml如下: [html] view plaincopyprint? <?xml version="1.0" encoding="UTF-8"?> <animation-list android:oneshot="false" xmlns:android="http://schemas.android.com/apk/res/android"> &

Android——进度条ProgressBar

1.activity_progressbar.xml <?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="

Android 进度条对话框ProgressDialog

<?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:ori

Android进度条使用详解(一)

进度条是UI界面中一种非常实用的组件,通常用于向用户像是某个耗时操作完成的百分比.进度条可动态地显示进度,因此避免长时间地执行某个操作时,让用户感觉程序失去了响应,从而更好地提高用户界面的友好性.ProgressBar本身代表着进度条组件,其子类还包括SeekBar(拖动条)和RatingBar(星级评分条). 一.ProgressBar使用详解 1.环形进度条使用方法 (1)进度条样式 (2)代码实现 <ProgressBar android:id="@+id/progressBar&q

Android进度条(星级评分)使用详解(二)

一.SeekBar拖动条使用 SeekBar继承于ProgressBar,ProgressBar所支持的XML属性和方法完全适用于SeekBar.拖动条和进度条的区别是:进度条采用颜色填充来表明进度完成的程度,而拖动条则通过滑块位置来标识数值并且运行用户拖动滑块来改变值.因此,拖动条通常用于对系统的某种数值进行调节,比如调节音量.图片的透明度等. 1.拖动条效果 2.代码实现 功能:通过拖动滑块该动态改变图片的透明度 public class MainActivity extends Actio

android 进度条ProgressBar样式设置

普通圆形ProgressBar 该类型进度条也就是一个表示运转的过程,例如发送短信,连接网络等等,表示一个过程正在执行中.一般只要在XML布局中定义就可以了. <progressBar Android:id="@+id/widget43" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="

&lt;Android&gt;进度条

Android中的进度条有多种:对话框进度条,标题栏进度条和水平进度条 1.对话框进度条 a)         覆盖Activity的onCreateDialog()方法,并在其中创建对话框. b)        调用Activity的showDialog()方法,显示进度条对话框. public class MainActivity extends Activity { private Button myBtn; @Override public void onCreate(Bundle sa

Android 进度条改变图片透明度

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:tools="http://schemas.android.com/tools" 4 android:layout_width="match_parent