Android中的AnalogClock Widget是一个时钟对象,本范例将配置一个小时钟,并在其下放置一个TextView,为了做对照,上面放置的是模拟时钟,下面的TextView则模拟电子时钟,将AnalogClock的时间以数字钟形式显示。
本范例的重点,在Android.os.Handler、java.lang.Thread以及Android.os.Message三对象的整合应用。通过产生Thread对象,在进程内同步调用System.currentTimeMillis()取得系统时间,并且通过Message对象来通知Handler对象,Handler则扮演联系Activity与Thread之间的桥梁,在收到Message对象后,将时间变量的值,显示于TextView当中,产生数字时钟的外观与功能。
主程序需要另外加载Java的Calendar与Thread对象,在onCreate()中构造Handler与Thread两对象,并实现handelMessage()与run()两个方法,如下所述:
/* import程序略 */
import android.widget.AnalogClock;
public class EX04_14 extends Activity
{
/*声明一常数作为判别信息用*/
protected static final int GUINOTIFIER = 0x1234;
/*声明两个widget对象变量*/
private TextView mTextView;
public AnalogClock mAnalogClock;
/*声明与时间相关的变量*/
public Calendar mCalendar;
public int mMinutes;
public int mHour;
/*声明关键Handler与Thread变量*/
public Handler mHandler;
private Thread mClockThread;
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/*通过findViewById取得两个widget对象*/
mTextView=(TextView)findViewById(R.id.myTextView);
mAnalogClock=(AnalogClock)findViewById(R.id.myAnalogClock);
/*通过Handler来接收进程所传递的信息并更新TextView*/
mHandler = new Handler()
{
public void handleMessage(Message msg)
{
/*处理信息的方法*/
switch (msg.what)
{
case EX04_14.GUINOTIFIER:
/* 在这处理要TextView对象Show时间的事件 */
mTextView.setText(mHour+" : "+mMinutes);
break;
}
super.handleMessage(msg);
}
};
/*通过进程来持续取得系统时间*/
mClockThread=new LooperThread();
mClockThread.start();
}
/*改写一个Thread Class用来持续取得系统时间*/
class LooperThread extends Thread
{
public void run()
{
super.run();
try
{
do
{
/*取得系统时间*/
long time = System.currentTimeMillis();
/*通过Calendar对象来取得小时与分钟*/
final Calendar mCalendar = Calendar.getInstance();
mCalendar.setTimeInMillis(time);
mHour = mCalendar.get(Calendar.HOUR);
mMinutes = mCalendar.get(Calendar.MINUTE);
/*让进程休息一秒*/
Thread.sleep(1000);
/*重要关键程序:取得时间后发出信息给Handler*/
Message m = new Message();
m.what = EX04_14.GUINOTIFIER;
EX04_14.this.mHandler.sendMessage(m);
}while(EX04_14.LooperThread.interrupted()==false);
/*当系统发出中断信息时停止本循环*/
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
其实要达到本范例效果的代码应该只有两行,也就是将笔者对于TextView与进程Thread的处理,改为使用widget.DigitalClock的方式,写法如下:
import android.widget.AnalogClock
mDigitalClock =(DigitalClock)findViewById(R.id.myDigitalClock);
而本程序使用TextView来模拟DigitalClock的做法,实际上,也是参考AnalogClock与DigitalClock这两个widget的代码所做的练习,对于将来实现Timer相关的小对象,会有所帮助。
Android提供了System.currentTimeMillis()、uptimeMillis()和elapsedRealtime()这三种不同特性的System Clock给开发者使用。本范例使用System.currentTimeMillis()就是标准的Clock用法,需要搭配真实的日期与时间使用,另外两者则是适用于interval与elapse time来控制程序与UI之用,读者可以自己练习。