本人最近在看android开发,想在一个TextView上显示当前的时间,当然时间是活动的就是要一直在获取,并不是获取一次。于是就想着要用带多线程,要单独一个线程来设置时间的显示。
一:错误的方法
直接写一个线程类,然后在run方法里调用setText()把时间设置到上面。
布局文件就是只有一个textview
import android.app.Activity;
import android.os.Bundle;
import android.text.format.Time;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView tv = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.textview1);
Thread myThread = new TimeThread();
myThread.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
class TimeThread extends Thread{
@Override
public void run() {
Time time = new Time();
while(true){
time.setToNow();
//System.out.println("当前时间:"+time.hour+":"+time.minute);
tv.setText("当前时间:"+time.hour+":"+time.minute);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
也就是启动了一个单另的线程用来处理时间,没有一点技术含量。从语法上看没有什么错误,但是程序总是闪退,于是我查阅了相关的资料,原来是android开发中的多线程不支持非主线程对UI界面的操作。因为这里的setText()不在主线程中而在myThread线程中,所以程序闪退。
二:正确的写法
这里用到了handler来处理相关问题。
思路:用handler将当前的时间实时的传递回主线程操纵UI。
界面布局有一个button,一个textView
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.format.Time;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
/**
* 用handler来获取非主线程的信息。
* 只有主线程才能修改ui
*
* */
public class MainActivity extends Activity {
private TextView tv = null;
private Button bn = null;
private Handler h = null;
Time timer = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.textView1);
bn = (Button)findViewById(R.id.button1);
bn.setOnClickListener(new MyListener());
h = new Myhandler();
timer = new Time();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
class MyListener implements OnClickListener{
public void onClick(View arg0) {
Thread t1 = new MyThread();
t1.start();
}
}
class Myhandler extends Handler{
@Override
public void handleMessage(Message msg) {//handler处理方法,我也不太懂,但是感觉在一个消息队列中,只要队列里有msg立即按顺序处理,所以只要有 //msg传来,立即设置到textview上,与主线程是异步执行的。setText对UI操作还在主线程中,所以符合规范。
tv.setText((String)msg.obj);
}
}
class MyThread extends Thread{
@Override
public void run() {
while(true){
timer.setToNow();
String my = "星期"+timer.weekDay+timer.hour+":"+timer.minute;
Message msg = h.obtainMessage();
msg.obj = my;
h.sendMessage(msg);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
本人初学android,很多地方也不清楚,这仅仅是这几天了解的一些简单的东西,和自己的解决方法,如果文章有技术问题还望指正。