从ADIL跨进程绑定通讯再探Service知识

之前写过一篇关于绑定前台Service实现APP安装包下载的文章

http://blog.csdn.net/androidmsky/article/details/53407925

今天自己也是温习了一下,确实普通应用开发Service用的比较少,不过他又是四大组件中仅次于Activity的家伙,所以决定再探Service。

设想场景,我们可以在一个独立进程的Service中进行复杂的计算,或者多媒体音乐的播放等。开启一个独立进程的优势主要就是系统会给我开启独立的内存空间从而突破一个程序(准确说是一个进程)的最大内存限制。当然对于多进程又有很多弊端,最大的弊端想必就是原来很方便的事变得复杂,原本同一进程的绑定方法的Binder将不可用。那么我们就可以通过AIDL来辅助进行绑定,从而实现Activity跨进程操作Service也就是本文的目标。

开发

1.先把Service放到另一个进程中:

 <service android:name=".MyService1"
                 android:process=":message"
            >
        </service>

好如果我们用普通的绑定方法,来绑定这个Service是可以成功绑定并启动的,但是

  @Override                                                          
  public void onServiceConnected(ComponentName arg0, IBinder service)

中的Service并不能强制转换成Service中的binder程序会报错,所以我们必须借助AIDL

2.创建一个AIDL文件并写随意两个方法

// IMyAidlService.aidl
package com.air.service;

// Declare any non-default types here with import statements

interface IMyAidlService {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
     void play(int i);
     int  add(int i);

    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);

}

写完之后rebulid一下项目,Android Studio 会帮我们自动生成相关的Java文件。
3.在Service中引用并实现相关方法。

private MyBinder mBinder = new MyBinder();

    class MyBinder extends IMyAidlService.Stub {


        @Override
        public void play(int i) throws RemoteException {

        }

        @Override
        public int add(int i) throws RemoteException {

            return ++i;
        }

        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }
    }

4.在Activity中绑定:

 class MyServiceConnection implements ServiceConnection {                       
     @Override                                                                  
     public void onServiceConnected(ComponentName arg0, IBinder service) {      
         Log.d("MyService123", "Service Connection Success");                   


         mMyBinder = IMyAidlService.Stub.asInterface(service);                  


         try {                                                                  
             Log.d("MyService123", "" + mMyBinder.add(10));                     
         } catch (RemoteException e) {                                          
             e.printStackTrace();                                               
         }                                                                      

          //同一进程的获取方法                                                                     
         //mMyBinder = (MyService1.MyBinder) service;                           


     }                                                                          

5.提供停止,解绑,开启,绑定四个方法

 public void stop(View v) {                                                 

     Intent stopIntent = new Intent(this, MyService1.class);                
     stopService(stopIntent);                                               

 }                                                                          

 //解绑                                                                        
 public void stop2(View v) {                                                
     unbindService(myServiceConnection);                                    


 }                                                                          


 public void start(View v) {                                                
      Intent startIntent = new Intent(this, MyService1.class);              
     startService(startIntent                                               

 }                                                                          

 public void bind(View v) {                                                 
     Intent intent = new Intent(this, MyService1.class);                    
     bindService(intent, myServiceConnection, Context.BIND_AUTO_CREATE);    
 }                                                                          

6.我们自定一个Application来看它的创建情况

public class A extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("MyService123","create");
    }
}

测试

好我们点击绑定按钮:

主进程输出日志:

06-27 15:26:33.367 26110-26110/com.air.service D/MyService123: create
06-27 15:26:35.458 26110-26110/com.air.service D/MyService123: Service Connection Success
06-27 15:26:35.460 26110-26110/com.air.service D/MyService123: 11

message进程输出日志:

06-27 15:35:53.947 32013-32013/com.air.service:message D/MyService123: create
06-27 15:35:53.949 32013-32013/com.air.service:message D/MyService123: onCreate() executed

可见我们成功使用了Service的add方法,得出数值11,Application也被两个进程分别创建了一次。

我们点击解除绑定按钮:
06-27 15:37:25.885 32013-32013/com.air.service:message D/MyService123: onDestroy() executed

Service成功被销毁。

如果我们先startService再绑定,再解绑会怎样?

我们会发现Service没有被销毁,如果再点击stop来停止Service,

06-27 15:39:39.156 32013-32013/com.air.service:message D/MyService123: onDestroy() executed

Service被成功销毁。

如果我们先startService再绑定,再停止Service会怎样?

其实是一样的Service没有被销毁,如果再点击stopService成功销毁。

总结

1.如果Service跨进程我们可以轻松的调起Service

2.如果Service跨进程我们可以绑定但不能通过原来的方法获取Binder实例

3.通过AIDL可以解决获取Binder实例的问题

4.如果Service即被绑定,又被开启,解绑和停止必须都执行才能正确的杀死Service。

5.Service放在独立进程中Application会被重复创建

本文代码链接:
https://github.com/AndroidMsky/AIDLBindService

哪里可以找到我:

我的Github: https://github.com/AndroidMsky

我的博客主页: http://blog.csdn.net/androidmsky

欢迎加作者自营安卓开发交流群: 308372687

这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值