一、Handler的基本使用
-
Handler一套Android消息传递机制,在多线程的应用场景中,将工作线程中需更新UI的操作信息传递到UI主线程,从而实现工作线程对UI的更新处理,最终实现异步消息的处理,多个线程并发更新UI的同时,保证线程安全。
-
使用方式
-
Handler的使用方式 因发送消息到消息队列的方式不同而不同,共分为2种:使用Handler.sendMessage()、使用Handler.post()
-
使用Handler.sendMessage(),新建Handler子类(内部类)
public class MainActivity extends AppCompatActivity { public TextView mTextView; public Handler mHandler; // 步骤1:(自定义)新创建Handler子类(继承Handler类) & 复写handleMessage()方法 class Mhandler extends Handler { // 通过复写handlerMessage() 从而确定更新UI的操作 @Override public void handleMessage(Message msg) { // 根据不同线程发送过来的消息,执行不同的UI操作 // 根据 Message对象的what属性 标识不同的消息 switch (msg.what) { case 1: mTextView.setText("执行了线程1的UI操作"); break; case 2: mTextView.setText("执行了线程2的UI操作"); break; } } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.show); // 步骤2:在主线程中创建Handler实例 mHandler = new Mhandler(); // 采用继承Thread类实现多线程演示 new Thread() { @Override public void run() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } // 步骤3:创建所需的消息对象 Message msg = Message.obtain(); msg.what = 1; // 消息标识 msg.obj = "A"; // 消息内存存放 // 步骤4:在工作线程中 通过Handler发送消息到消息队列中 mHandler.sendMessage(msg); } }.start(); // 步骤5:开启工作线程(同时启动了Handler) // 此处用2个工作线程展示 new Thread() { @Override public void run() { try { Thread.sleep(6000); } catch (InterruptedException e) { e.printStackTrace(); } // 通过sendMessage()发送 // a. 定义要发送的消息 Message msg = Message.obtain(); msg.what = 2; //消息的标识 msg.obj = "B"; // 消息的存放 // b. 通过Handler发送消息到其绑定的消息队列 mHandler.sendMessage(msg); } }.start(); } }
-
使用Handler.sendMessage(),匿名内部类
public class MainActivity extends AppCompatActivity { public TextView mTextView; public Handler mHandler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.show); // 步骤1:在主线程中 通过匿名内部类 创建Handler类对象 mHandler = new Handler(){ // 通过复写handlerMessage()从而确定更新UI的操作 @Override public void handleMessage(Message msg) { // 根据不同线程发送过来的消息,执行不同的UI操作 switch (msg.what) { case 1: mTextView.setText("执行了线程1的UI操作"); break; case 2: mTextView.setText("执行了线程2的UI操作"); break; } } }; // 采用继承Thread类实现多线程演示 new Thread() { @Override public void run() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } // 步骤3:创建所需的消息对象 Message msg = Message.obtain(); msg.what = 1; // 消息标识 msg.obj = "A"; // 消息内存存放 // 步骤4:在工作线程中 通过Handler发送消息到消息队列中 mHandler.sendMessage(msg); } }.start(); // 步骤5:开启工作线程(同时启动了Handler) // 此处用2个工作线程展示 new Thread() { @Override public void run() { try { Thread.sleep(6000); } catch (InterruptedException e) { e.printStackTrace(); } // 通过sendMessage()发送 // a. 定义要发送的消息 Message msg = Message.obtain(); msg.what = 2; //消息的标识 msg.obj = "B"; // 消息的存放 // b. 通过Handler发送消息到其绑定的消息队列 mHandler.sendMessage(msg); } }.start(); } }
-
使用 Handler.post()
public class MainActivity extends AppCompatActivity { public TextView mTextView; public Handler mHandler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.show); // 步骤1:在主线程中创建Handler实例 mHandler = new Handler(); // 步骤2:在工作线程中 发送消息到消息队列中 & 指定操作UI内容 new Thread() { @Override public void run() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } // 通过psot()发送,需传入1个Runnable对象 mHandler.post(new Runnable() { @Override public void run() { // 指定操作UI内容 mTextView.setText("执行了线程1的UI操作"); } }); } }.start(); // 步骤3:开启工作线程(同时启动了Handler) // 此处用2个工作线程展示 new Thread() { @Override public void run() { try { Thread.sleep(6000); } catch (InterruptedException e) { e.printStackTrace(); } mHandler.post(new Runnable() { @Override public void run() { mTextView.setText("执行了线程2的UI操作"); } }); } }.start(); } }
-
二、Handler机制的工作流程
-
异步通信准备
-
消息发送
-
消息循环
-
消息处理