1.首先是一个简单的例子:
package com.example.ThreadTest;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener {
Button StartThreadButton,endThreadButton;
TextView textView;
//小技巧:int->String的方法,num_String + num
int num=0;
String num_String = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StartThreadButton = (Button)findViewById(R.id.button1);
StartThreadButton.setOnClickListener(this);
endThreadButton =(Button)findViewById(R.id.button2);
endThreadButton.setOnClickListener(this);
textView = (TextView)findViewById(R.id.textView1);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.button2:
controlHandler.post(controlRunnable);
break;
case R.id.button1:
controlHandler.removeCallbacks(controlRunnable);
break;
default:
break;
}
}
//创建Handler对象以控制线程Runnable
Handler controlHandler = new Handler();
//创建Runnable,定义进程行为
Runnable controlRunnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
textView.setText(num_String+num);
num++;
//通过controlHandler的postDelayed方法实现将目标线程反复压入队列(延迟1000ms)
controlHandler.postDelayed(controlRunnable, 1000);
}
};
}
但要注意此处的Handler跟MainActivity处于同一线程,即未真正创建新的线程,调用controlHandler.post(controlRunnable)时只是直接调用了controlRunnable.run()方法。
可通过在合适位置插入
System.out.println("The Bundler thread-->"+Thread.currentThread().getId() );
System.out.println("The Bundler thread-->"+Thread.currentThread().getName() );
来验证此观点。
2.既然上述直接通过Handler.post()方法无法真正创建新线程,那么如何才能新建线程呢?
方法一:同样还是一个相对简单的方法
Thread t = new Thread(Runnable r);
t.start();
下面是修改过的Runnable()
Runnable controlRunnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
//注意不能再次使用textView,因为textView是由MainActivity所在的main进程所建立的,不同进程间不能直接调用
//textView.setText(num_String+num);
num++;
System.out.println("The number-->" + num);
//此处就不应用postDelayed()再次回到刚才的main线程了
// controlHandler.postDelayed(controlRunnable, 1000);
System.out.println("The Bundler thread-->"+Thread.currentThread().getId() );
System.out.println("The Bundler thread-->"+Thread.currentThread().getName() );
}
};
方法二:Looper
package com.example.ThreadTest;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.app.Activity;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.out.println("The main thread-->"+Thread.currentThread().getId() );
System.out.println("The main thread-->"+Thread.currentThread().getName() );
//生成一个HandlerThread对象
HandlerThread handlerThread = new HandlerThread("handler_thread");
handlerThread.start();
//使用HandlerThread生成的对象来获取Looper
MyHandler myHandler = new MyHandler(handlerThread.getLooper());
Message msg = myHandler.obtainMessage();
msg.sendToTarget();
//或者可以使用下述方法发送msg对象
//myHandler.sendMessage(msg);
}
class MyHandler extends Handler{
public MyHandler() {
// TODO Auto-generated constructor stub
}
public MyHandler(Looper looper){
super(looper);
}
//重写handleMessage(Message msg)方法来实现操作
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
//将需要的操作放到handleMessage中来,即发送消息
System.out.println("The Bundler thread-->"+Thread.currentThread().getId() );
System.out.println("The Bundler thread-->"+Thread.currentThread().getName() );
}
}
}