Service 与 Activity 通信

ServiceActivity 之间可以通过绑定来实现通信;
我们在项目 ServiceSample代码基础上动手实现这个功能吧。

实验步骤:

  1. Service 中创建一个内部类,继承自 Binder
  2. 覆写ServiceonBind()onUnbind() 函数;
  3. Activity中创建 ServiceConnection 类的实例;
  4. ServiceConnection 类实例中获取Binder对象(在步骤 1 中创建的类型),通过该对象实现ActivityService的通信;
  5. Activity中实现绑定、解绑Service的操作

1. 在Service 中创建一个内部类,继承自 Binder

编辑 MyService创建一个内部类,
Java 代码:

    public class MyBinder extends Binder {
    
    
        public void doSomething() {
    
    
            Log.i(TAG, "MyBinder : doSomething()");
        }
    }

Kotlin 代码:

    class MyBinder: Binder() {
    
    
        fun doSomething() {
    
    
            Log.i(TAG, "MyBinder : doSomething()")
        }
    }

在内部类实现了一个函数 doSomething(),打印日志。

2. 覆写ServiceonBind()onUnbind() 函数;

编辑 MyService,覆写onBind()onUnbind() 函数。
onBind()函数在ServiceActivity 成功绑定的时候回调;
onUnbind() 函数在ServiceActivity 解除绑定的时候回调

Java 代码:

    private final MyBinder mBinder = new MyBinder();
    @Override
    public IBinder onBind(Intent intent) {
    
    
        Log.i(TAG, "onBind()");
        return mBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
    
    
        Log.i(TAG, "onUnbind()");
        return super.onUnbind(intent);
    }

Kotlin 代码:

    private val mBinder = MyBinder()
    override fun onBind(intent: Intent): IBinder {
    
    
        Log.i(TAG, "onBind()")
        return mBinder
    }

    override fun onUnbind(intent: Intent?): Boolean {
    
    
        Log.i(TAG, "onUnbind()")
        return super.onUnbind(intent)
    }

我们创建了一个 MyBinder 对象,并在onBind()函数中返回该对象。

3. 在Activity中创建 ServiceConnection 类的实例;

MainActivity中创建一个 ServiceConnection 类的实例,

Java 代码:

    private final ServiceConnection connection = new ServiceConnection() {
    
    
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
    
    
            Log.i(TAG, "onServiceConnected()");
            if (iBinder == null) return;
            MyService.MyBinder mBinder = (MyService.MyBinder) iBinder;
            mBinder.doSomething();
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
    
    
            Log.i(TAG, "onServiceDisconnected()");
        }
    };

Kotlin 代码:

    private val connection = object : ServiceConnection {
    
    
        override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) {
    
    
            Log.i(TAG, "onServiceConnected()")
            if (iBinder == null) return
            val mBinder = iBinder as MyService.MyBinder
            mBinder.doSomething()
        }

        override fun onServiceDisconnected(name: ComponentName?) {
    
    
            Log.i(TAG, "onServiceDisconnected()")
        }
    }

4. 获取Binder对象(在步骤 1 中创建的类型),通过该对象实现ActivityService的通信

onServiceConnected() 函数中得到 IBinder 对象,它就是 MyBinder的实例,我们可以调用它的函数、传参数,通过这个对象实现ActivityService的通信,

5. 在Activity中实现绑定、解绑Service的操作

编辑布局文件 activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:padding="15dp"
    tools:context=".MainActivity">

    ......

    <Button
        android:id="@+id/bindBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="bind" />

    <Button
        android:id="@+id/unbindBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="unbind" />

</LinearLayout>

界面添加了两个按钮,分别用于控制绑定、解绑Service

添加事件监听

编辑 MainActivity,给按钮加上事件监听,分别实现绑定、解绑Service的操作。

Java 代码:

    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ......

        Button bindBtn = findViewById(R.id.bindBtn);
        bindBtn.setOnClickListener(view -> {
    
    
            Log.i(TAG, "bindService clicked.");
            Intent intent = new Intent(this, MyService.class);
            bindService(intent, connection, Context.BIND_AUTO_CREATE);
        });

        Button unbindBtn = findViewById(R.id.unbindBtn);
        unbindBtn.setOnClickListener(view -> {
    
    
            Log.i(TAG, "unbindService clicked.");
            unbindService(connection);
        });
    }

Kotlin 代码:

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        ......

        val bindBtn = findViewById<Button>(R.id.bindBtn)
        bindBtn.setOnClickListener {
    
    
            Log.i(TAG, "bindService clicked.")
            val intent = Intent(this, MyService::class.java)
            bindService(intent, connection, Context.BIND_AUTO_CREATE)
        }

        val unbindBtn = findViewById<Button>(R.id.unbindBtn)
        unbindBtn.setOnClickListener {
    
    
            Log.i(TAG, "unbindService clicked.")
            unbindService(connection)
        }
    }

运行项目

  • 点击绑定按钮,查看日志:
    log

  • 点击解绑按钮,查看日志:
    l2

只要调用方ActivityService之间的连接没有断开, Service就会一直保持运行状态,直到被系统回收。
调用ContextunbindService()函数可以解除两者之间的绑定关系。

猜你喜欢

转载自blog.csdn.net/flyingyajun/article/details/127073344
今日推荐