在循环中handler.sendMessage(msg)后,利用Looper.loop()来调用handler.handleMessage(msg),如何让loop()退出执行下个迭代?
[code="java"]
public class MainActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyView view = new MyView(this, null);
setContentView(view);
}
// 自定义视图类
class MyView extends View implements Runnable{
// 图形当前坐标
private int x=20, y=20;
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// 获得焦点
setFocusable(true);
// 启动线程
new Thread(this).start();
}
@Override
public void run() {
Looper.prepare();
Handler refreshHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==0x101111){
MyView.this.update();
MyView.this.invalidate();
}
}
};
while(!Thread.currentThread().isInterrupted()){
// 通过发送消息更新界面
Message msg = refreshHandler.obtainMessage();
msg.what = 0x101111;
refreshHandler.sendMessage(msg);
Looper.loop();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 实例化画笔
Paint paint = new Paint();
// 设置画笔颜色
paint.setColor(Color.GREEN);
// 画圆
canvas.drawCircle(x, y, 10, paint);
}
// 更新坐标
private void update(){
int h = 500;
y += 5;
if(y>=h)
y = 20;
}
}
}
[/code]
完全正确,因为你只send了一次message,handler当然只执行一次handleMessage。
你的第一个问题补充说的很正确。另外这个例子写的很蹊跷。在handler的同一个线程中执行执行它的sendMessage,还有什么用呢,跟直接的函数调用又有什么却别呢?完全失去了用Handler的意义。Handler和Looper这个模型就是为了处理其他线程间的消息传递,在同一个线程内就失去意义了。
Looper负责处理消息循环,Looper.loop()是开始消息循环,调用它之后循环已经开始,下一个由handler发的message将会被这个handler的handleMessage方法处理。这是一个----循环
只要你能访问refreshHandler,并用发调用sendMessage发消息,该消息就会被refreshHandler所在线程的消息队列并将由handleMessage处理。你所要做的只是refreshHandler.sendMessage,其他的就不用管了。多次调用refreshHandler.sendMessage也没有关系,消息都会被送到refreshHandler所在线程的消息队列,它自己将处理
在这个例子中,你应该把
[code="java"]
Handler refreshHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==0x101111){
MyView.this.update();
MyView.this.invalidate();
}
}
};
[/code]
这段,拿到run方法外面,这样的话就不用Looper了,因为主线程会有默认的Looper对象除了消息,不用在程序中写。这是主线程跟其他线程区别的地方