使用 Handler 机制,首先需要创建一个Handler 对象,可以直接使用Handler 无参构造函创建Handler 对象,或者是继承Handler类,重写 handleMessage(Message msg)方法来创建handler对象。Google 官方提供了一个推荐的使用方式,代码如下∶
Class LooperThread extends Thread {
public Handler mHandler;public void run(){Looper.prepare();mHandler = new Handler(){public void handleMessage(Message msg){// process incoming messages here }};Looper.loop();}}复制代码通过上一部分的分析,读者应该能够很容易理解上面这种方式。但是在实际的开发实践中,大部分的Handler 对象都是在主线程中创建的,此时已经存在了Looper 对象,并不需要调用Loopr.prepare()与 Looper.loop()方法,直接构建一个Handler 对象即可∶
private Handler mHandler = new Handler() {
public void handleMessage(Message msg){// process incoming messages here}};复制代码这里我们使用Handler的sendMessage(Message msg)方法来发送消息,并使用handleMessage(Message msg)方法来接收消息,在布局代码中加入两个按钮,与两个TextView,当程序运行10秒修改TextView的内容,布局文件activity_main.xml代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <Button android:id="@+id/bind_service" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="绑定服务" android:textSize="25dp"/> <Button android:id="@+id/unbind_service" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="解绑服务" android:textSize="25dp"/> <TextView android:id="@+id/textview" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="无数据" android:textSize="25dp"/> <TextView android:id="@+id/handler_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="handler" android:textSize="25dp"/></LinearLayout>复制代码我们创建MyService类继承自Service,Myservice代码如下:
package com.rfstar.handlertest;
import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.util.Log;import androidx.annotation.Nullable;public class MyService extends Service { private String message; private IBinder binder = new MyBinder(); private MyService.ServiceThread serviceThread=new MyService.ServiceThread(); private Thread thread; @Override public IBinder onBind(Intent intent) { Log.i("service", "onBind"); // serviceThread = new ServiceThread(); thread = new Thread(serviceThread); //开启一个线程 thread.start(); /**返回一个可以在Activity的onServiceConnected()方法中接收到的binder对象 * 它是Activity和Service通信的桥梁 * 在Activity中通过这个bind对象可以得到Service的实例引用 * 通过获取的Service实例就可以调用相关方法和属性 */ return binder; } @Override public void onCreate() { Log.i("service", "onCreate"); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i("service", "onStartCommand"); return super.onStartCommand(intent, flags, startId); } @Override public boolean onUnbind(Intent intent) { Log.i("service", "onUnbind"); return super.onUnbind(intent); } @Override public void onDestroy() { super.onDestroy(); //结束run方法的循环 serviceThread.flag = false; Log.i("service", "onDestroy"); } class ServiceThread implements Runnable { //用volatile修饰保证变量在线程间的可见性 volatile boolean flag = true; @Override public void run() { Log.i("service", "thread 开始运行"); int i = 1; while (flag) { if (mOnDataCallback != null) //通过线程模拟真实场景,循环改变数据 { mOnDataCallback.onDataChange(message + i); } i++; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } public class MyBinder extends Binder { public void setData(String message) { //从Activity传入message值 MyService.this.message=message; } public MyService getService() { /** * 返回当前MyService对象 * 当Activity中获取binder类的实例后 * 可以通过此方法获取Service类实例 */ return MyService.this; } } private OnDataCallback mOnDataCallback=null; public void setOnDataCallback(OnDataCallback mOnDataCallback) { this.mOnDataCallback=mOnDataCallback; } public interface OnDataCallback{ void onDataChange(String message); }}复制代码
然后再在AndroidManifest.xml文件中配置service,一定不要忘记这一步,否则工程运行不了。
在Activity中,创建Handler,并使用Handler发送消息,代码如下:
这里分别使用 mHandler.sendMessage(msg1)、mHandler.sendEmptyMessage(2)两种方式来送消息,并在 handleMessage(Message msg)中用 switch(msg.what) 来分别获取。同时还用了mhandler.post(new Runnable(){})这样一个与 runOnUiThread(Thread thread)同样效果的方法。Handler 的其他几个方法与上述3种用法一致,稍加改动就可以使用,此处不再叙述。运行程序,绑定服务之后,当第 10秒之后可以看到 TextView 的值被修改,如图1-1所示第20秒之后,Toast 出现,效果如图1-2所示。
图1-1 使用sendMessage方法发送消息
图1-2使用post方法发送消息
文章评论(0条评论)
登录后参与讨论