等了一晚上也没有人回答,我自已就重新看了一遍代码,发现我的思路是有问题的。
我在第二篇的代码中,是这样实现循环的:
我在主线程的run方法中调用handler.sendMessage(msg)
而在handler的sendMessage中使用 post方法将run放置在消息队列中
这样相互调用形成了一个循环
然后使用handler的removeCallbacks将run从消息队列中去除,从而中断跳出循环
这样整个循环是在主线程的message queue中形成的。
而我在第三篇中,想要用新建的线程来实现计数的时候,仍然按照上面的思路来写,就有个问题:当我在主线程中使用handler的post方法时,实际上是将新建线程中的run方法在主线程执行(放到主线程的message queue中)
这样其实整个过程还是在主线程中运行的
经过一夜的思索,我突然意识到,我其实是要在新建的线程中实现计数的功能,那就应该让循环在新建的线程中实现
于是我把代码改成了下面的样子
我在代码中加入一个静态的变量running,用于控制新线程中的循环计数
我在新线程中写入一个循环,当running为true时,循环计数,并调用handler.sendMessage(msg)为主线程传递计数结果
package com.example.handler4;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
public class MainActivity extends Activity {
Button startButton = null;
Button stopButton = null;
ProgressBar progressbar = null;
Thread counter = null;
//线程执行的标志,当为true时,线程中继续循环
static boolean running = true;
//获取主线程的looper
Looper looper = Looper.getMainLooper();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startButton = (Button) findViewById(R.id.startButton);
stopButton = (Button) findViewById(R.id.stopButton);
progressbar = (ProgressBar) findViewById(R.id.progressBar);
//为button绑定onclicklistener
startButton.setOnClickListener(new ButtonOnclickListener());
stopButton.setOnClickListener(new stopOnclickListener());
}
class ButtonOnclickListener implements OnClickListener{
public void onClick(View v) {
progressbar.setVisibility(View.VISIBLE);
counter = new Thread(){
int i = 1;
@Override
public void run() {
// TODO Auto-generated method stub
while(running){
i += 10;
Message msg = handler.obtainMessage();
msg.arg1 = i;
//让线程延迟一秒
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
Log.i("run", "run "+i+"%");
Log.i("run", Thread.currentThread().getName());
msg.sendToTarget();
if(i>100)
//当计数超过一百时,跳出循环
running = false;
}
}
};
counter.start();
}
}
class stopOnclickListener implements OnClickListener{
public void onClick(View v) {
//点击取消按钮,分线程不再循环计数
running = false;
//让progressbar置成隐藏
progressbar.setVisibility(View.GONE);
}
}
//将handler与主线程关联
Handler handler = new Handler(looper){
public void handleMessage(android.os.Message msg) {
int i =msg.arg1;
//根据message中传来的参数控制进度条
progressbar.setProgress(i);
Log.i("run", Thread.currentThread().getName());
if(i>100){
//如果进度条慢,进度条隐藏
progressbar.setVisibility(View.GONE);
}
};
};
}
后台打印日志的截图:
这样,问题基本解决了,感觉自己对多线程的理解还是太浅了,很多时候容易想当然的来也代码,没有深刻理解代码背后的含义。还是要继续努力啊,当然还是要说一句,根据网上大神的说法,在android中多线程更多的是用AsyncTask,而不是Thread和Handler去更新UI。接下来,我就开始学习AsyncTask的用法。