等了一晚上也没有人回答,我自已就重新看了一遍代码,发现我的思路是有问题的。
我在第二篇的代码中,是这样实现循环的:
我在主线程的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的用法。