編輯:關於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設備之間可以除了通過wifi熱點共享上網,還可以通過藍牙共享上網,後面這個功能很少人使用,但適合某台設備沒有wifi卻有藍牙的情況。一、設置WT19i,系統
在OC中,我們可以通過Category 對已有的類進行擴展,這得益於OC的Runtime機制,讓類可以‘動態’的添加方法以及實現。但是,在Cate
多線程案例——計時器 這個案例中,屏幕啟動之後,進入如圖所示的界面。 屏幕上有一個文本框用於顯示逝去的時間,此外還有一個“停止計時”按鈕。案例的用例圖如圖所示。 &nbs
ZXing是一個開放源碼的,用Java實現的多種格式的1D/2D條碼圖像處理庫,它包含了聯系到其他語言的端口。Zxing可以實現使用手機的內置的攝像頭完成條