保证服务既能长期运行,又能调用服务里的方法的方案

Android服务绑定与调用
本文介绍了一种在Android中确保服务长期运行并能被调用的方法,通过startService和bindService结合使用,并展示了如何通过IBinder接口实现服务的远程调用。
   保证服务既能长期运行,又能调用服务里的方法的方案:
步骤一:startService方式启动服务,会执行服务的onCreate方法和onStartCommand方法;
步骤二:bindService方式绑定服务,会执行服务的onBind方法(不会再执行onCreate方法,因为第一步已经执行了);
步骤三:unbindService方式解除绑定,会执行服务的onUnbind方法,但是不会执行服务的onDestroy方法,因为第一步是以startService方式启
       动的服务,这就限制解除绑定时销毁服务了,只可以通过stopService方式销毁服务;
步骤四:如果需要销毁服务,则通过stopService方式销毁服务。


    我认为比较连贯的做法是,一,在服务调用者的Activity的onCreate方法中,先启动服务startService,再绑定服务bindService ;二、在服务调用者的Activity的onDestroy方法中执行解绑unbindService方法,具体看案例


绑定服务调用服务的方法(无论本地绑定还是远程绑定),要注意的问题,当服务绑定成功后,中间人(IBinder)的实例就通过onServiceConnected传递给绑定者了(成员变量),这样,即使你解除绑定甚至销毁服务,该中间人实例已经在调用者这里了,仍然可以调用服务的方法,可通过解绑后将中间人实例置为null来验证,具体看案例

案例:游戏(支付方)和支付宝(Service),游戏应用调用支付宝服务

支付宝的服务的代码:

一:清单文件中服务的生命

<service android:name="com.yin.zhifubao.ALiPayService">
            <intent-filter >
                <action android:name="com.yin.zhifubao.ALiPayService.pay"/>
            </intent-filter>
        </service>
二:.aidl文件

package com.yin.zhifubao;

interface IPayMethod {
boolean callMethodInService(int age,long time,String pwd);
}
三:服务的.java

public class ALiPayService extends Service {
/**
 * 绑定服务
 */
	@Override
	public IBinder onBind(Intent intent) {
		System.out.println("执行onBind");
		return new PayMethod();
	}
/**
 * 解除绑定
 */
	@Override
		public boolean onUnbind(Intent intent) {
		System.out.println("执行onUnbind");
		return super.onUnbind(intent);
		}
	/**
	 * 创建服务
	 */
	@Override
		public void onCreate() {
		System.out.println("执行onCreate");
	}
	/**
	 * 启动服务
	 */
	@Override
		public int onStartCommand(Intent intent, int flags, int startId) {
		System.out.println("执行onStartCommand");
		return super.onStartCommand(intent, flags, startId);
		}
	/**
	 * 销毁服务
	 */
	@Override
		public void onDestroy() {
		System.out.println("执行onDestroy");
		super.onDestroy();
		}
	/**
	 * 阿里服务中的支付方法
	 */
	public boolean payMethod(int age,long time,String pwd){
		if("123".equals(pwd)){
			return true;
		}
		return false;
	}
	/**
	 * 定义一个中间人
	 */
	private class PayMethod extends IPayMethod.Stub{
		@Override
		public boolean callMethodInService(int age, long time, String pwd)
				throws RemoteException {
			//调用服务中的方法
			return payMethod(age, time, pwd);
		}
	}
}

游戏的代码:

一:.aidl文件
package com.yin.zhifubao;

interface IPayMethod {
boolean callMethodInService(int age,long time,String pwd);
}

二:启动绑定服务的代码

public class MainActivity extends Activity {
private IPayMethod im;
private MyConn conn;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
//		//启动服务
//		Intent intent = new Intent();
//		intent.setAction("com.yin.zhifubao.ALiPayService.pay");
//		startService(intent);
//		//绑定服务
//		if(conn==null){
//			conn=new MyConn();
//		}
//		bindService(intent, conn, BIND_AUTO_CREATE);
	}
	/**
	 * 绑定服务com.yin.zhifubao
	 */
	public void bind(View v){
		Intent intent = new Intent();
		intent.setAction("com.yin.zhifubao.ALiPayService.pay");
		if(conn==null){
			conn=new MyConn();
		}
		bindService(intent, conn, BIND_AUTO_CREATE);
		/**
		 * 不可以绑定服务后立刻调用服务的方法,因为bindService和ServiceConnection的onServiceConnected方法是异步的,
		 * 绑定成功后不可以立刻得到im的实例,这个规则不仅使用于远程绑定,也适用于本地绑定
		 */
//		try {
//			boolean boo=im.callMethodInService(10, 100, "123");
//			if(boo==true){
//				Toast.makeText(MainActivity.this, "恭喜,用支付宝买炮弹成功", Toast.LENGTH_SHORT).show();
//			}else{
//				Toast.makeText(MainActivity.this, "悲剧,用支付宝买炮弹失败", Toast.LENGTH_SHORT).show();
//			}
//		} catch (RemoteException e) {
//			System.out.println("调用服务的方法失败");
//			e.printStackTrace();
//		}
	}
	/**
	 * 解除绑定
	 */
	public void unbind(View v){
		if(conn!=null){
			unbindService(conn);
			conn=null;
//			im=null;
		}
	}
	/**
	 * 调服务的方法
	 * @param v
	 */
	public void buy(View v){
		if(im==null){
			Toast.makeText(this, "远程服务异常", Toast.LENGTH_SHORT).show();
		}else{
			try {
			boolean boo=im.callMethodInService(10, 100, "123");
			if(boo==true){
				Toast.makeText(this, "恭喜,用支付宝买炮弹成功", Toast.LENGTH_SHORT).show();
			}else{
				Toast.makeText(this, "悲剧,用支付宝买炮弹失败", Toast.LENGTH_SHORT).show();
			}
		} catch (RemoteException e) {
			System.out.println("调用服务的方法失败");
			e.printStackTrace();
		}
		}
	}
	/**
	 * 启动服务
	 * @param v
	 */
	public void start(View v){
		Intent intent = new Intent();
		intent.setAction("com.yin.zhifubao.ALiPayService.pay");
		startService(intent);
	}
	/**
	 * 停止服务
	 * @author Administrator
	 *
	 */
	public void stop(View v){
		Intent intent = new Intent();
		intent.setAction("com.yin.zhifubao.ALiPayService.pay");
		stopService(intent);
	}
	private class MyConn implements ServiceConnection{
		//与服务绑定成功执行的方法
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			System.out.println("执行onServiceConnected");
			im=IPayMethod.Stub.asInterface(service);

		}
		//与服务异常断开连接执行的方法
		@Override
		public void onServiceDisconnected(ComponentName name) {
			System.out.println("执行onServiceDisconnected");
			
		}
		
	}
	@Override
		protected void onDestroy() {
//		if(conn!=null){
//			unbindService(conn);
//		}
		super.onDestroy();
		}
}




评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值