绑定式服务是安卓编程过程中不可回避的一个问题,而且再完成客户端与服务端的交互方面有得天独厚的优势,但是在刚开始学习的时候,这一部分的编程思路比较难以理解,结合自己的所学心得,笔者从新手角度分析绑定时服务的应用方法。

绑定时服务实现步骤

运用基本的程序对绑定式服务的编码步骤进行归纳:

1. 自定义服务类

GetDistanceService

private Random random=new Random();
private  IBinder mybinder=new IBinder();

public GetDistanceService() {

}

public class IBinder extends Binder {

    GetDistanceService  getGetDistanceService(){
        return GetDistanceService.this;
    }

}

@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    return mybinder;
}

public double getDistance(){
    return random.nextDouble();
}

其中特别需要注意的是要自定义一个Bind的子类IBinder ,这个类对于绑定时服务的内容实现来说非常重要,IBinder 类可以理解为一个服务和前台Activity的通道,可以在自定义的IBinder 子类中结合实际添加一些功能方法,而后将onBind(Intent intent)函数的返回值改为自定义IBinder 子类的一个实例。在自定义的服务类中,可以自定义一些方法(本文中为 getDistance)便于前台调用。

2. 实例化ServiceConnection类

在前台的Activity类中新建ServiceConnection类的实例conection作为成员变量,在OnCreate()方法中将conection变量实例化。

protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       connection = new ServiceConnection() {
           @Override
           public void onServiceConnected(ComponentName name, IBinder service) {
               GetDistanceService.IBinder binder = (GetDistanceService.IBinder) service;
               disService = binder.getGetDistanceService();
               binded = true;
           }

           @Override
           public void onServiceDisconnected(ComponentName name) {
               binded = false;
           }
       };
       displayDis();
   }

ServiceConnection类是实现前端Activity和服务交互功能的关键,里面定义了前台需要调用那些服务端的功能,也就是交互的逻辑定义。但是在此时尚未绑定服务。

3. 在前台的Activity类的OnStart()方法中绑定服务

super.onStart();
        Intent intent = new Intent(MainActivity.this, GetDistanceService.class);

这一环节必须在onCreate()方法之后,因为在上一步完成了ServiceConnection变量的实例,通过 bindService(intent, connection, BIND_AUTO_CREATE)完成了服务绑定工作

4.在界面Activity中进行完成相应的功能实现

MainActivity

private ServiceConnection connection;
private GetDistanceService disService;
private Boolean binded = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            GetDistanceService.IBinder binder = (GetDistanceService.IBinder) service;
            disService = binder.getGetDistanceService();
            binded = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            binded = false;
        }
    };

    displayDis();


}

private void displayDis() {


    final Handler handler = new Handler();
    handler.post(new Runnable() {
        @Override
        public void run() {
            if (disService != null || binded) {
                TextView disText = findViewById(R.id.destanceDisplay);
                disText.setText(Double.toString(disService.getDistance()));
            } else
                Toast.makeText(MainActivity.this, "disService=null", Toast.LENGTH_LONG);
            handler.postDelayed(this, 1000);
        }
    });


}

@Override
protected void onStart() {
    super.onStart();
    Intent intent = new Intent(MainActivity.this, GetDistanceService.class);
    bindService(intent, connection, BIND_AUTO_CREATE);
}

@Override
protected void onStop() {
    super.onStop();
    unbindService(connection);
}

关键解读

ServiceConnection的主要功能是运用Service交互传递过来的Bind类的实例完成功能逻辑的准备工作,比如说获取服务类实例等。
Bind类主要是提供给前端Activity与服务交互的通道,类似于信使之类,是交互的介质
要注意bindService()的调用时机,一定要在ServiceConnection实例化之后,否则会出错。

希望对你有所帮助,谢谢!