原创 Android之Handler机制使用实例

2021-11-2 12:18 2264 18 18 分类: 软件与OS 文集: android studio

使用 Handler 机制,首先需要创建一个Handler 对象,可以直接使用Handler 无参构造函创建Handler 对象,或者是继承Handler类,重写 handleMessageMessage 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
  • }
  • };
  • 复制代码

    这里我们使用HandlersendMessage(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发送消息,代码如下:

    package com.rfstar.handlertest;
  • import androidx.appcompat.app.AppCompatActivity;
  • import android.content.ComponentName;
  • import android.content.Context;
  • import android.content.Intent;
  • import android.content.ServiceConnection;
  • import android.os.Bundle;
  • import android.os.Handler;
  • import android.os.IBinder;
  • import android.os.Message;
  • import android.view.View;
  • import android.widget.Button;
  • import android.widget.TextView;
  • import android.widget.Toast;
  • public class MainActivity extends AppCompatActivity implements View.OnClickListener {
  • private Button bindService;
  • private Button unbindService;
  • private TextView textView;
  • private TextView handlderText;
  • @Override
  • protected void onCreate(Bundle savedInstanceState) {
  • super.onCreate(savedInstanceState);
  • setContentView(R.layout.activity_main);
  • initView();
  • }
  • private void initView() {
  • bindService=(Button)findViewById(R.id.bind_service);
  • unbindService=(Button)findViewById(R.id.unbind_service);
  • textView=(TextView)findViewById(R.id.textview);
  • handlderText=(TextView)findViewById(R.id.handler_text);
  • bindService.setOnClickListener(this);
  • unbindService.setOnClickListener(this);
  • }
  • @Override
  • public void onClick(View view) {
  • switch (view.getId()){
  • case R.id.bind_service:
  • //创建意图
  • Intent bindIntent=new Intent(this,MyService.class);
  • //绑定服务
  • bindService(bindIntent,serviceConnection, Context.BIND_AUTO_CREATE);
  • break;
  • case R.id.unbind_service:
  • //创建意图
  • Intent unbindIntent=new Intent(this,MyService.class);
  • //解绑服务
  • unbindService(serviceConnection);
  • break;
  • }
  • }
  • @Override
  • protected void onDestroy()
  • {
  • super.onDestroy();
  • unbindService(serviceConnection);
  • }
  • private MyService.MyBinder myBinder;
  • private MyService myService;
  • public ServiceConnection serviceConnection=new ServiceConnection() {
  • @Override
  • public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
  • //得到binder实例
  • myBinder=(MyService.MyBinder)iBinder;
  • //给Service中的message设置一个值
  • myBinder.setData("MainActivity:");
  • //得到Service实例
  • myService=myBinder.getService();
  • //设置接口回调获取Service中的数据
  • myService.setOnDataCallback(new MyService.OnDataCallback() {
  • @Override
  • public void onDataChange(final String message) {
  • if(message.equals("MainActivity:"+10))
  • {
  • Bundle bundle=new Bundle();
  • bundle.putString("name","大鸟科创空间");
  • Message msg1=mHandler.obtainMessage();
  • msg1.setData(bundle);
  • msg1.what=1;
  • msg1.arg1=6;
  • mHandler.sendMessage(msg1);
  • }else if(message.equals("MainActivity:"+20))
  • {
  • mHandler.sendEmptyMessage(2);
  • }else{
  • mHandler.post(new Runnable() {
  • @Override
  • public void run() {
  • textView.setText(message);
  • }
  • });
  • }
  • }
  • });
  • }
  • @Override
  • public void onServiceDisconnected(ComponentName componentName) {
  • myService=null;
  • }
  • };
  • private Handler mHandler=new Handler(){
  • public void handleMessage( Message msg) {
  • switch (msg.what){
  • case 1:
  • String name=(String)msg.getData().get("name");
  • int age=msg.arg1;
  • handlderText.setText(name+"的年龄为:"+age);
  • break;
  • case 2:
  • Toast.makeText(MainActivity.this,"发送的一个空的Message",Toast.LENGTH_LONG).show();
  • break;
  • }
  • }
  • };
  • }
  • 复制代码

    分别使用 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方法发送消息

    作者: 大鸟科创空间, 来源:面包板社区

    链接: https://mbb.eet-china.com/blog/uid-me-3949041.html

    版权声明:本文为博主原创,未经本人允许,禁止转载!

    PARTNER CONTENT

    文章评论0条评论)

    登录后参与讨论
    我要评论
    0
    18
    关闭 站长推荐上一条 /3 下一条