編輯:關於Android編程
1.Handler是什麼?
Handler是Android給我們提供的一套更新UI的機制,也封裝了一套消息處理的機制,可以發送消息,也可以通過它處理消息。
eg:Handler在Framework中常見,比如Activity的生命周期onCreate,onResume,onDestroy這些方法究竟在什麼時候被調用呢,其實查看Framework源碼就會發現,
所有的Activity回調方法都是通過Handler發送消息,根據不同的Message做相應的分支處理,告訴Framework去回調activity onCreate,onResume方法。
在Framework中,Activity的交互大部分都是用AMS(Activity Manager Service)做處理的。
在應用程序中,一個核心的類就是ActivityThread,ActivityThread中就是通過Handler接收到AMS給我們發送的Activity生命周期的一些管理,AMS發送一個啟動Activity的一 個實例,那麼我們整個ActivityThread接收到這個實例就會回調Activity onCreate方法。
回調機制就是通過Handler機制詳細的回調處理信息的。
2.為什麼要用Handler?
不用Handler機制是不行的。
Android在設計的時候就封裝了一套消息創建、傳遞、處理機制,如果不遵循這樣的機制就沒辦法更新UI信息,就會拋出異常信息。
異常就是不能在非UI線程中更新UI
3.Handler怎麼用呢?
下面是Google官方的API:

翻譯:
一個Handler 允許你發送和處理一個Message或者Runable對象,跟線程的MessageQueen進行關聯,每個Handler實例與一個線程進行綁定,這個線程是帶有MessageQueen的一個線程。當你創建一個新的handler的時候,默認會綁定到創建線程的MessageQueeen當中,從這點可以知道,它將要傳遞和處理消息並執行消息在MessageQueen當中,並從MessageQueen當中進行移除。
意思就是:創建一個Handler的時候會和默認的線程進行綁定,默認的線程中有個MessageQueen,MessageQueen字面上就是消息隊列的意思。

翻譯:Handler主要有兩個用途:一個是定時的發送Message和Runable對象,二是在一個線程當中處理並執行一個action,一個動作。

翻譯:當你創建一個應用程序的時候會創建一個進程,進程在Activity中就是一個UI線程(ActivityThread線程),在UI線程中,系統會默認的創建一個Looper,這個Looper和UI線程,MessageQueen有一定的聯系。。主線程主要是運行一個MessageQueen管理頂級的應用程序(Activity,BroadcastReceiver)。Activity,BroadcastReceiver默認創建在ActivityThread當中。
Handler的四種用法:
post(Runable)
postDelayed(Runable,long)
sendMessage
sendMessageDelayed
代碼示例1:post(Runable)
獲取一個textView控件,讓其5秒之後修改textView的內容(因為要5秒,所以啟用子線程)
public class MainActivity extends AppCompatActivity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.textView); new Thread() { @Override public void run() { super.run(); try { Thread.sleep(5000); textView.setText("你好世界"); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); } }
報錯:不能在非UI線程(子線程)中更新UI 所以使用handler從子線程發送消息到主線程更新UI
注意:Handler導入android:os的包
public class MainActivity extends AppCompatActivity {
private TextView textView;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
new Thread() {
@Override
public void run() {
super.run();
try {
Thread.sleep(5000);
handler.post(new Runnable() {
@Override
public void run() {
textView.setText("你好世界");
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
}
代碼示例2:postDelayed(Runable,long)
淘寶上每隔一段時間定期換一張圖片的效果
public class MainActivity extends AppCompatActivity {
private ImageView imageView;
private int images[] = {R.drawable.a, R.drawable.b, R.drawable.c};
private int index;
private Handler handler = new Handler();
private MyRunable myRunable = new MyRunable();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.imageView);
handler.postDelayed(myRunable, 1000);//調用
}
class MyRunable implements Runnable {
@Override
public void run() {
index++;
index = index % 3;//讓圖片循環播放
imageView.setImageResource(images[index]);
handler.postDelayed(myRunable, 1000);
}
}
}
代碼示例3:sendMessage
在子線程中用handler發送消息(sendMessage)給handler,handler會接收消息並打印出來
public class MainActivity extends AppCompatActivity {
private TextView textView;
//重寫handleMessage方法接收發送過來的消息
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
textView.setText(msg.arg1 + " " + msg.arg2 + " " + msg.obj);
}
};
class Person {
private int age;
private String name;
@Override
public String toString() {
return "age==" + age + " " + "name==" + name;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
// Message message = new Message();
Message message = handler.obtainMessage();
message.arg1 = 88;
message.arg2 = 100;
Person person = new Person();
person.age = 15;
person.name = "小紅";
message.obj = person;
handler.sendMessage(message);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
//創建Message對象有兩種方法:
new Message返回一個message對象
handler.obtainMessage()返回一個message對象
查看源碼:

this指的是handler自己,target指消息發送給handler
handler發送消息也有兩種方式:
handler.sendMessage();
message.sendToTarget();
代碼示例4:handler移除消息,調用handler.removeCallbacks(myRunable)
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private ImageView imageView;
private int images[] = {R.drawable.a, R.drawable.b, R.drawable.c};
private int index;
private Handler handler = new Handler();
private MyRunable myRunable = new MyRunable();
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.imageView);
findViewById(R.id.button).setOnClickListener(this);
handler.postDelayed(myRunable, 1000);//調用
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.button:{
handler.removeCallbacks(myRunable);
}
}
}
class MyRunable implements Runnable {
@Override
public void run() {
index++;
index = index % 3;//讓圖片循環播放
imageView.setImageResource(images[index]);
handler.postDelayed(myRunable, 1000);
}
}
}
代碼示例5:通過Callback接口攔截發送過來的消息,如果為true成功截獲不執行後邊的代碼,如果為false, 就執行
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button button;
private Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message message) {
Toast.makeText(MainActivity.this, "AAA", Toast.LENGTH_SHORT).show();
return true;
}
}){
@Override
public void handleMessage(Message message) {
Toast.makeText(MainActivity.this,"BBB", Toast.LENGTH_SHORT).show();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(this);
}
@Override
public void onClick(View view) {
handler.sendEmptyMessage(0);
}
}
Android設備間實現藍牙(Bluetooth)共享上網
Android設備之間可以除了通過wifi熱點共享上網,還可以通過藍牙共享上網,後面這個功能很少人使用,但適合某台設備沒有wifi卻有藍牙的情況。一、設置WT19i,系統
Objective-C Runtime 解析(四)—— 在Category中添加屬性
在OC中,我們可以通過Category 對已有的類進行擴展,這得益於OC的Runtime機制,讓類可以‘動態’的添加方法以及實現。但是,在Cate
android 多線程技術應用
多線程案例——計時器 這個案例中,屏幕啟動之後,進入如圖所示的界面。 屏幕上有一個文本框用於顯示逝去的時間,此外還有一個“停止計時”按鈕。案例的用例圖如圖所示。 &nbs
Android二維碼開源項目zxing編譯
ZXing是一個開放源碼的,用Java實現的多種格式的1D/2D條碼圖像處理庫,它包含了聯系到其他語言的端口。Zxing可以實現使用手機的內置的攝像頭完成條