Android 移动开发 | bindService 绑定服务详细过程~

前言

我们都知道,在Activity中要启动Service有两种方式,一种是startService(),还有另一种是bindService(),两者的使用场景不一样,启动的参数也不同,下面我们要说的是bindService绑定服务:

bindService 绑定服务

bindService可以实现在同个应用程序(or 组件)之间调用,这是在同一个进程中,也可以在不同应用程序之间调用,即跨进程通信

bindService 绑定服务详细过程

1. 自定义一个Service(BindService),在这个Service内创建一个内部类(MyBinder)并继承Binder实现自己的IBinder接口对象,在这个内部类(MyBinder)中定义一个方法返回当前Service实例,即返回BindService实例;

     // 2. 实例化一个MyBinder对象mybinder,而mybinder这个对象实现了客户端(调用者)与服务端(Service)的通信
public class BinderService extends Service {
    public BinderService() {
    }

    private MyBinder  mybinder = new MyBinder();
    
    // 1. 自定义一个内部类MyBinder类继承Binder, 从而实现IBinder接口
    class MyBinder extends Binder{

        public BinderService getService() {
            return BinderService.this;   //返回当前Service类
        }
    }
}
2. 通过onBind( )方法返回自己的IBinder对象;

 // 必须实现的方法,绑定该Service时会回调onBind()方法  
    @Override  
    public IBinder onBind(Intent intent) {  
        Log.i("BindService", "onBind方法被调用!服务绑定成功!");  
        return mybinder;  
    }  
    
3.在绑定该Service的类中实例化ServiceConnection接口的实现类,重写onServiceConnected()和onServiceDisconnected()方法,然后直接读取IBinder传递过来的参数;

因为系统会调用onServiceConnected(),从而读取传递服务的 onBind() 方法所返回的 IBinder对象。


    ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.i("MainActivity","执行了onServiceConnected(),当前Acitivity与服务连接成功");
            mybinder = (BinderService.MyBinder) service;

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i("MainActivity","执行了onServiceDisconnected(),当前Acitivity与服务断开连接");
        }
    };
4. 在绑定该Service的类中的onCreate()方法里,创建Intent对象 并通过bindService()并绑定服务;
// 4. 创建Intent对象 并通过bindService()并绑定服务
         Intent bindIntent = new Intent(this,BinderService.class);
         bindService(bindIntent,conn,BIND_AUTO_CREATE); 
5. 解绑服务
  // 调用onUnbind和onDestroyed方法,解绑服务
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(conn);
    }

整个过程:
使用BindService绑定Service的过程中:

  1. 程序依次先调用onCreate(),onBind()方法,可以在onBind()方法中返回自定义的IBinder对象;
  2. 再接着调用的是 ServiceConnection的onServiceConnected()方法该方法中可以获得 IBinder对象,从而进行相关通信;
  3. 当Service解除绑定后会自动调用 onUnbind和onDestroyed方法,当绑定多客户端情况下需要解除所有的绑定才会调用onDestoryed方法进行销毁。

完整code

MainActivity.java
package com.example.service;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn_bindService;
private Button btn_unbindService;
private BinderService.MyBinder mybinder;


    ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.i("MainActivity","执行了onServiceConnected(),当前Acitivity与服务连接成功");
            mybinder = (BinderService.MyBinder) service;

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i("MainActivity","执行了onServiceDisconnected(),当前Acitivity与服务断开连接");
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_bindService = (Button)findViewById(R.id.btn_bindService);
        btn_unbindService = (Button)findViewById(R.id.btn_unbindService);
        btn_bindService.setOnClickListener(this);
        btn_unbindService.setOnClickListener(this);
    }

    public void onClick(View v){
        switch (v.getId()){
            case R.id.btn_bindService:
                // 4. 创建Intent对象 并通过bindService()并绑定服务
                Intent bindIntent = new Intent(this,BinderService.class);
                bindService(bindIntent,conn,BIND_AUTO_CREATE);
                break;
            case R.id.btn_unbindService:
                unbindService(conn);
                break;
            default:
                break;
        }
    }

    //  在onDestroy()方法里,解绑服务
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(conn);
    }
}

BinderService.java
package com.example.service;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import java.util.List;

public class BinderService extends Service {

    //1. 自定义一个内部类MyBinder类继承Binder,,从而实现IBinder接口
    class MyBinder extends Binder{

        public BinderService getService() {
            return BinderService.this;   //返回当前Service类
        }
    }

    //2. 实例化 一个MyBinder 对象
    private MyBinder  mybinder = new MyBinder();


    public BinderService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        Log.i("MyService","执行了onBind(),服务绑定成功");
        return mybinder;
    }



    @Override
    public boolean onUnbind(Intent intent) {
        Log.i("MyService","执行了onUnbind(),服务解绑成功");
        return super.onUnbind(intent);
    }

    @Override
    public void onCreate() {
        Log.i("MyService","执行了onCreste(),服务创建成功");
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("MyService","执行了onStartCommand(),服务启动成功");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Log.i("MyService","执行了onDestroy(),服务被销");
        super.onDestroy();
    }
    
}
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:orientation="vertical"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center">
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="服务绑定"
            android:id="@+id/btn_bindService"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="服务解绑"
            android:id="@+id/btn_unbindService"/>
    </LinearLayout>

</LinearLayout>

bindService启动方式调用执行的顺序是:
onCreate,接着在调用onBind方法,而onStartCommand这方法在bindService启动这个方式中并不调用;

在Service中执行顺序:
  1. 在Service内部用内部类得到mybinder对象
  2. 在onBind方法中返回IBinder实例,返回实例可以是Service实例本身 或者 通过mybinder获取Service公共的方法。如上面第一,二步的方法,这样客户端可以通过该方法得到相应的Service实例,接着调用者客户端执行的流程,客户端执行流程步骤如下:
调用者(客户端)执行的流程
  1. 先创建ServiceConnetion实例,并重写其方法
  2. 当执行了onServiceConnected回调时,我们可以通过IBinder实例得到Service实例对象 或 直接调用binder公共方法,这样就实现了client(客户端)和service(服务端)的连接。

注意:
client和Service解除绑定时,onServiceDisconnected并不会被调用;onServiceDisconnected被调用的情况是发生在client和Service连接意外丢失时,这时client和Service一定是断开连接了。

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值