• Android菜鸟的成长笔记(18)——绑定本地Service并与之通信


    在上一篇中介绍了Service与Activity的区别及Service两种启动方式中的第一种启动方式startService().

    我们会发现用startService()、stopService()方法启动和关闭一个Service时,Service与访问者之间基本上不存在太多的关联,因此Service和访问者之间也无法进行通信和数据交换。如果要实现Service与Activity之间的通信就要使用第二种启动方式(绑定启动)bindService()启动、unbindService()关闭。

    下面我们来看一下bindService方法的各个参数的含义:(下图是API中关于该方法的说明)

    官方说明地址:http://developer.android.com/reference/android/content/Context.html#bindService(android.content.Intent, android.content.ServiceConnection, int)

    各个参数的大致含义如下:

    service:通过Intent指定要启动的Service.

    conn:该参数是一个ServiceConnection对象,该对象用于监听访问者与Service对象的onServiceConnected(ComponentName name, IBinder service)方法:当Service所在的宿主进程由于异常终止或者由其他原因终止,导致该Service与访问者之间断开连接时回调该ServiceConnection对象的onServiceDisconnected(ComponentName name)方法。

    	private ServiceConnection conn = new ServiceConnection() {
    		
    		@Override
    		public void onServiceDisconnected(ComponentName name) {
    			System.out.println("--Service Disconnected--");
    		}
    		
    		@Override
    		public void onServiceConnected(ComponentName name, IBinder service) {
    			System.out.println("--Service Connected--");
    			binder = (MyBinder) service;
    		}
    	};

    flags:指定绑定时是否自动创建Service.该参数为0则不自动创建,为BIND_AUTO_CREATE(自动创建)

    注意:当调用者主动通过nubindService()方法断开与Service的连接时,ServiceConnection对象的onServiceDisconnected(ComponentName name)方法不会被调用。

    可以看到上面onServiceConnected方法中有一个IBinder的参数对象,实际上Activity与Service之间的绑定是通过该参数进行绑定和通信的。这时候可能有的朋友就有点迷糊了,这到底是怎样实现通信的呢?

    其实,当你在开发一个Service的时候Service类会强制你实现一个方法onBind(Intent intent).在绑定本地(没有跨越进程)Service的情况下,onBind(Intent intent)方法返回的IBinder对象将会传给上面介绍的bindService()方法参数ServiceConnection对象的o中的IBinder.这样访问者就可以通过操作该参数中IBinder对象来实现对Service中数据的读取。

    在实际开发中通常会采用继承Binder(IBinder的实现类)的方式实现自己的IBinder对象。

    下面我们来实现一个绑定的Service与Activity之间的通信:

    (1)建立一个service返回Binder对象

    package com.example.testservice;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;
    
    public class BindService extends Service{
    	
    	private int count;
    	private boolean quit;
    	//定义onBinder方法所返回的对象
    	private MyBinder binder = new MyBinder();
    	//通过继承Binder来实现IBinder类
    	public class MyBinder extends Binder{
    		public int getCount(){
    			return count;
    		}
    	}
    	
    	@Override
    	public IBinder onBind(Intent intent) {
    		System.out.println("Service is Binded");
    		return binder;
    	}
    	
    	@Override
    	public void onCreate() {
    		
    		super.onCreate();
    		System.out.println("Service is Created");
    		new Thread(){
    			public void run() {
    				while(!quit){
    					try {
    						Thread.sleep(1000);
    					} catch (InterruptedException e) {
    						// TODO Auto-generated catch block
    						e.printStackTrace();
    					}
    					count++;
    				}
    			};
    		}.start();
    	}
    	
    	@Override
    	public boolean onUnbind(Intent intent) {
    		System.out.println("Service is UnBinded");
    		return super.onUnbind(intent);
    	}
    	
    	@Override
    	public void onDestroy() {
    		super.onDestroy();
    		this.quit = true;
    		System.out.println("Service is Destroyed");
    	}
    	
    
    }
    (2)创建ServiceConnection接口实例对象,并将该对象的实例作为参数传给bindService()方法,通过调用ServiceConnection接口实例中的nServiceConnected方法的参数获得IBinder对象。
    package com.example.testservice;
    
    import android.app.Activity;
    import android.app.Service;
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.IBinder;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.Toast;
    
    import com.example.testservice.BindService.MyBinder;
    
    public class BindServiceTest extends Activity{
    	Button bind, unbind, getServiceStatus;
    	
    	BindService.MyBinder binder;
    	
    	private ServiceConnection conn = new ServiceConnection() {
    		
    		@Override
    		public void onServiceDisconnected(ComponentName name) {
    			System.out.println("--Service Disconnected--");
    		}
    		
    		@Override
    		public void onServiceConnected(ComponentName name, IBinder service) {
    			System.out.println("--Service Connected--");
    			binder = (MyBinder) service;
    		}
    	};
    	
    	protected void onCreate(android.os.Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.main);
    		
    		bind = (Button)findViewById(R.id.button1);
    		unbind = (Button) findViewById(R.id.button2);
    		getServiceStatus = (Button) findViewById(R.id.button3);
    		
    		final Intent intent = new Intent();
    		
    		intent.setAction("com.meritit.service.BIND_SERVICE");
    		
    		bind.setOnClickListener(new OnClickListener() {
    			
    			@Override
    			public void onClick(View arg0) {
    				bindService(intent, conn, Service.BIND_AUTO_CREATE);
    			}
    		});
    		
    		unbind.setOnClickListener(new OnClickListener() {
    			
    			@Override
    			public void onClick(View v) {
    				unbindService(conn);
    			}
    		});
    		
    		getServiceStatus.setOnClickListener(new OnClickListener() {
    			
    			@Override
    			public void onClick(View v) {
    				Toast.makeText(BindServiceTest.this, "Service的count值是:" + binder.getCount(),
    						Toast.LENGTH_SHORT).show();
    			}
    		});
    	};
    }
    通过该方法Activity可以非常方便的访问到Service的运行状态,这里的IBinder可以看成Service组件所返回的代理对象。


    下一篇将介绍:Service的生命周期






  • 相关阅读:
    【08】Python数据分析基础
    C#类和类成员初始化顺序
    C# 在子窗体调用父窗体的值(转)
    求实对称阵的 特征值 和 特征向量(转)
    Dev express 笔记
    Arcgis桌面开发,Python引用GDAL库的方法
    操作系统学习笔记--第三章--进程
    操作系统学习笔记--第一章--计算机系统概述
    GIS专业分析方法(待更新)
    C#中不用安装Oracle客户端连接Oracle数据库(转)
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6469467.html
Copyright © 2020-2023  润新知