android中Handler的初步認識(四)

   等了一晚上也沒有人回答,我自已就重新看了一遍代碼,發現我的思路是有問題的。 

   我在第二篇的代碼中,是這樣實現循環的

       我在主線程的run方法中調用handler.sendMessage(msg)

              而在handlersendMessage中使用 post方法將run放置在消息隊列中

       這樣相互調用形成了一個循環

       然後使用handlerremoveCallbacksrun從消息隊列中去除,從而中斷跳出循環

       這樣整個循環是在主線程的message queue中形成的。


   而我在第三篇中,想要用新建的線程來實現計數的時候,仍然按照上面的思路來寫,就有個問題:當我在主線程中使用handlerpost方法時,實際上是將新建線程中的run方法在主線程執行(放到主線程的message queue

這樣其實整個過程還是在主線程中運行的

 

    經過一夜的思索,我突然意識到,我其實是要在新建的線程中實現計數的功能,那就應該讓循環在新建的線程中實現

 

   於是我把代碼改成了下面的樣子

   我在代碼中加入一個靜態的變量running,用於控制新線程中的循環計數

   我在新線程中寫入一個循環,當runningtrue時,循環計數,並調用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的用法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章