Andorid 多线程(三):Handler 消息传递机制
haovin https://blog.csdn.net/haovin/article/details/89600054
一.Android中的HandlerThread
1.1主要用途
a、定时器,未来某时做某事
b、线程之间传递消息
c、嵌入式:apk 调用SystemService 时,权限不够,由Handler 传递消息,可以获得 system jurisdiction
注意:handler对线程的处理post,并不是启动了一个新的线程,而是在当前线程调用run方法。
二.Handler的使用
2.1 定时器
package com.gatsby.handlerdelaytime; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.View; import android.widget.Button; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { Button btn1,btn2; int count = 0; Handler handler = new Handler();//创建一个Handler对象: private Runnable runnable = new Runnable() { @Override public void run() { Log.d("gatsby", "Thread.currentThread().getId()->"+Thread.currentThread().getId()); count++; Log.d("gatsby", "count=" + count); handler.postDelayed(runnable, 1000);//1秒后调用此Runnable对象 } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn1 = (Button) this.findViewById(R.id.btn1); btn2 = (Button) this.findViewById(R.id.btn2); btn1.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { Thread thread = new Thread(runnable); thread.start(); } }); btn2.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { handler.removeCallbacks(runnable);//关闭此定时器 } }); } }
package com.gatsby.handlerrunnable; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.View; import android.widget.Button; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity implements View.OnClickListener { Button btn1, btn2; Handler mhandler = new Handler();//创建一个Handler对象 private Runnable runnable = new Runnable() { @Override public void run() { Log.d("gatsby", "Handler DelayRunable!"); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn1 = (Button) findViewById(R.id.btn1); btn2 = (Button) findViewById(R.id.btn2); btn1.setOnClickListener(this); btn2.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn1: Log.d("gatsby","onClick btn1!"); mhandler.postDelayed(runnable, 2000); break; case R.id.btn2: mhandler.removeCallbacks(runnable); break; } } }
2.2 使用方式
Handler的使用方式可以根据发送消息的方式不同而分为两种:
Handler.sendMessage()和Handler.post()
2.3 Ed Sheeran
方式一、使用Handler.sendMessage()
a、创建Handler子类
package com.gatsby.handlertest; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.Button; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity implements View.OnClickListener { TextView tv1; Button btn1; // 2、在主线程中创建自定义Handler(mHandler)的实例 private CrushHandler crushHandler = new CrushHandler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv1 = (TextView) findViewById(R.id.tv1); btn1 = (Button) findViewById(R.id.btn1); btn1.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn1: MyRunnable(); break; } } public void MyRunnable() { Runnable runnable = new Runnable() { @Override public void run() { // 3、创建所需消息对象 Message msg = Message.obtain(); msg.what = 1; //4、发送消息 crushHandler.sendMessage(msg); } }; Thread thread = new Thread(runnable); thread.start(); } //1、自定义Handler子类,继承Handler,重写handleMessage()方法 class CrushHandler extends Handler { @Override public void handleMessage(@NonNull Message msg) { super.handleMessage(msg); //执行的UI操作 tv1.setText("新建Handler子类方法"); } } }
创建Handler子类 1、自定义Handler子类,并重写handleMessage()方法 class CrushHandler extends Handler { //重写handleMessage()方法 @Override public void handleMessage(@NonNull Message msg) { super.handleMessage(msg); //执行的UI操作 tv1.setText("新建Handler子类方法"); } } 2、主线程中创建mHandler的实例 private CrushHandler crushHandler = new CrushHandler(); 3、在子线程中创建需要发送的消息对象 Message msg = Message.obtain(); msg.what = 1; 4、在子线程中通过Hander发送消息到消息队列 crushHandler.sendMessage(msg); 5、启动子线程
b、使用匿名内部类
package com.gatsby.handlertest; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.Button; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity implements View.OnClickListener { TextView tv1; Button btn1; //1、在主线程中通过匿名内部类创建Handler类对象 private Handler mHandler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { //执行的UI操作 tv1.setText("匿名内部类方法"); return false; } }); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv1 = (TextView) findViewById(R.id.tv1); btn1 = (Button) findViewById(R.id.btn1); btn1.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn1: MyRunnable(); break; } } public void MyRunnable() { Runnable runnable = new Runnable() { @Override public void run() { // 2、创建所需消息对象 Message msg = Message.obtain(); msg.what = 1; //3、发送消息 mHandler.sendMessage(msg); } }; Thread thread = new Thread(runnable); thread.start();//4、开启线程 } }
方式二、post方法
post机制将runnable对象运行在主线程中的
package com.gatsby.handlertest; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.widget.Button; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity implements View.OnClickListener { TextView tv1; Button btn1; //1、在主线程中创建Handler的实例 private Handler mHandlerPost = new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv1 = (TextView) findViewById(R.id.tv1); btn1 = (Button) findViewById(R.id.btn1); btn1.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn1: Thread thread = new CrushThread(); thread.start(); break; } } class CrushThread extends Thread { @Override public void run() { Runnable runnable = new Runnable() { @Override public void run() { tv1.setText("post方法"); } }; mHandlerPost.post(runnable); } } }