Android之Handler探索

来源:http://www.cnblogs.com/bingbingliang-xiaomonv/archive/2016/05/06/5462685.html
-Advertisement-
Play Games

Handler背景理解: Handler被最多的使用在了更新UI線程中,但是,這個方法具體是什麼樣的呢?我在這篇博文中先領著大家認識一下什麼是handler以及它是怎麼樣使用在程式中,起著什麼樣的作用。 示例說明: 首先先建立兩個按鈕:一個是start按鈕,作用是開啟整個程式。另一個是終止按鈕end ...


Handler背景理解: 

 Handler被最多的使用在了更新UI線程中,但是,這個方法具體是什麼樣的呢?我在這篇博文中先領著大家認識一下什麼是handler以及它是怎麼樣使用在程式中,起著什麼樣的作用。

  示例說明:

    首先先建立兩個按鈕:一個是start按鈕,作用是開啟整個程式。另一個是終止按鈕end,作用是結束整個的程式。這兩個按鈕的相互對比就會讓大家明白Handlerd的基本的工作原理。

運行結果截圖:

MainActivity.class

package com.example.testhandler;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {
	
	private Button start,end;

	//實例化一個handler對象
	private Handler handler = new Handler();
	//開啟一個新的線程:開啟線程有兩種方式,一種是使用普通的Thread方法,另一個中是使用Runnable方法
	Runnable update = new Runnable() {
		
		@Override
		public void run() {
			System.out.println("update");
			handler.postDelayed(update, 3000);
		}
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		start = (Button)this.findViewById(R.id.btn_start);
		end = (Button)this.findViewById(R.id.btn_end);
		
		start.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				//加入到隊列中去執行
				handler.post(update);
			}
		});
		
		end.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				//將消息移除隊列中去
				handler.removeCallbacks(update);
			}
		});
		
	}

}

  當點擊Start按鈕時的效果圖如下:

當點擊end按鈕時的效果圖如下:

註意:

  Handler中的post方法並沒有開啟一個新的線程,他的操作是在主線程中執行的。下麵咱們就來驗證一下這個觀點。

  首先先貼一下運行截圖:

  

  等過10s之後的運行結果是:

  

這裡只是測試一下handler的post()方法是否是在主線程中進行的。所以沒有佈局。

設計思路:

在主線程中輸出主線程當前的ID和Name,然後使用Runnable方式新建一個線程,在這個新線程中讓程式睡眠10s,將這個線程使用Handler的post()方法發送到主線程中,看是否是執行非同步載入。也就是驗證handler是否是非同步載入方式。結論:Handler不是非同步載入方式。

MainActivity:

package com.example.handlertest1;

import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

	private Handler mhandler = new Handler();
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//將多線程發送到消息隊列中
		mhandler.post(r);
		//不會立刻載入界面,這說明瞭handler並不是開闢了一個新的線程而是在主線程中進行的。
		setContentView(R.layout.activity_main);
		System.out.println("Activity-->"+Thread.currentThread().getId());
		System.out.println("Activity-->"+Thread.currentThread().getName());
	}

	Runnable r = new Runnable() {
		public void run() {
			System.out.println("Handler--->"+Thread.currentThread().getId());
			System.out.println("handler--->"+Thread.currentThread().getName());
			try {
				Thread.sleep(10000);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	};
	
}

LogCat文件的輸出:

 

在這裡通過ID號很明顯的看出這不是執行的是多線程載入

在上面的主線程中重新新建一個線程則實現了多線程的載入:

將上面的onCreate()中的代碼替換為:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //將多線程發送到消息隊列中
//        mhandler.post(r);
        //不會立刻載入界面,這說明瞭handler並不是開闢了一個新的線程而是在主線程中進行的。
        setContentView(R.layout.activity_main);
        //這是另外開啟了一個新的線程,會發現這裡輸出的速率會比上次的快很多
        Thread t = new Thread(r);
        t.start();
        System.out.println("Activity-->"+Thread.currentThread().getId());
        System.out.println("Activity-->"+Thread.currentThread().getName());
    }

效果截圖如下:

LogCat文件中的輸出結果截圖為:

 

在這裡通過ID號很明顯的看出了這是執行了多線程載入。

  Handler要想開闢一個新的線程需要使用HanderThread()方法。下麵就是HandlerThread()的用法:

設計思路:

  通過使用handler方法傳輸數據,然後使用HandlerThread,實現了使用Looper來處理消息隊列的功能。輸出當前的Activity的ID和Name,以及Handler的ID和Name以及傳輸的數據

代碼如下:

 1 package com.example.handlertest1;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.os.Handler;
 6 import android.os.HandlerThread;
 7 import android.os.Looper;
 8 import android.os.Message;
 9 
10 public class HandlerTest2 extends Activity{
11 
12     @Override
13     protected void onCreate(Bundle savedInstanceState) {
14         super.onCreate(savedInstanceState);
15         setContentView(R.layout.activity_main);
16         
17         //列印當前線程的ID和當前線程的名字
18         System.out.println("Activity-->"+Thread.currentThread().getId());
19         System.out.println("Activity-->"+Thread.currentThread().getName());
20         
21         //HandlerThread是以鍵值對的形式進行存儲的,這裡的handler_thread就是該handler的鍵名
22         //生成一個HandlerThread對象,實現了使用Looper來處理消息隊列的功能。這是有android來提供的並不是java中的Thread提供
23         HandlerThread handlerthread = new HandlerThread("handler_thread");
24         handlerthread.start();
25         MyHandler myhandler = new MyHandler(handlerthread.getLooper());
26         Message msg = myhandler.obtainMessage();
27         //傳送多的數據的時候使用的setData()方法,使用Bundle()將數據包裝
28         Bundle b = new Bundle();
29         b.putInt("age", 20);
30         b.putString("name", "張三");
31         msg.setData(b);
32         //將消息發送給目標,目標就是生成該msg對象的handler
33         msg.sendToTarget();
34         
35     }
36     
37     class MyHandler extends Handler{
38         
39         public MyHandler(){
40             
41         }
42         public MyHandler(Looper looper){
43             super(looper);
44         }
45         
46         @Override
47         public void handleMessage(Message msg) {
48             Bundle b = msg.getData();
49             int age = b.getInt("age");
50             String name = b.getString("name");
51             System.out.println("age is"+age+",name"+name);
52             System.out.println("Handler--->"+Thread.currentThread().getId());
53             System.out.println("Handler--->"+Thread.currentThread().getName());
54             System.out.println("handlermessage");
55         }
56         
57     }
58     
59 }

好了,就這麼多了,具體的關於Handler、Looper、Message三者的關係,參考http://blog.csdn.net/lmj623565791/article/details/38377229個人感覺不錯


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.Volley和Gson結合使用——Volley適用於小型數據,多次的請求,使用Gson解析時,伺服器數據的鍵值不能包含常用的標識符如:class.....等,這些就需要與服務端小伙伴商量了, public class MainActivity extends Activity { private ...
  • 用UICollectionView實現無限輪播圖 效果 源碼 https://github.com/YouXianMing/Animations 細節 ...
  • 1.打開資料庫 #import "ViewController.h" #import "FMDB.h" @interface ViewController () @property (nonatomic, strong) FMDatabase *db; @end @implementation Vi ...
  • 關於PagerAdapter的粗略翻譯 英文版api地址:PagerAdapter(自備梯子) PagerAdapter instantiateItem(ViewGroup,int) destroyItem(ViewGroup,int,Onject) getCount() isViewFromObj ...
  • title: Android N開發 你需要知道的一切 tags: Android N,Android7.0,Android 轉載請註明出處:http://www.cnblogs.com/yishaochu/p/5465413.html 一、前言 如果你英文不錯建議你去官網看,官網底部也有翻譯語言選 ...
  • 開發者設計界面時候往往不會使用系統自帶的標題欄,因為不美觀,所以需要自己設置標題欄。 1.根據需求在xml文件中設置標題佈局 2.在values的styles中將以上標題設置成自己的style 3.在醒目清單文件中用到該主題的activity的標簽中加入 android:theme="@style/ ...
  • 項目做多了之後,會發現其實 ScrollView嵌套ListVew或者GridView等很常用,但是你也會發現各種奇怪問題產生。根據個人經驗現在列出常見問題以及代碼最少最簡單的解決方法。 問題一 : 嵌套在 ScrollView的 ListVew數據顯示不全,我遇到的是最多只顯示兩條已有的數據。 解 ...
  • 初始化是為了使用某個類、結構體或枚舉類型的實例而進行的準備過程。這個過程包括為每個存儲的屬性設置一個初始值,然後執行新實例所需的任何其他設置或初始化。 初始化是通過定義構造器(Initializers)來實現的,這些構造器可以看做是用來創建特定類型實例的特殊方法。與 Objective-C 中的構造 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...