android 的 service远程运用

Service 是 android的一个重要组建,用到的地方也比较多。

Service 上一章讲的是本地服务,现在讲讲远程服务,即跨进程服务。
如果是本地服务,按照下面的写法

    public class MyService extends Service {  
 
        @Override  
        public void onCreate() {  
            super.onCreate();  
            try {  
                Thread.sleep(60000);  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  
 
    }  

在activity中点击Start Service按钮,开启该服务,会发现,几秒钟后程序报出了ANR异常提示框。这是因为本地service也是在UI线程中,如果要做耗时操作,可以在里面开启一个子线程,在子线程中做耗时操作,操作完成后,可以和广播配合,把数据发回activity中。
把一个本地服务变成远程服务,很简单,在配置清单里面,服务配置的节点里,添加  <service android:process=":remote" > 即可。
我们重新点击Start Service按钮,发现没有ANR异常,因为该service和UI线程已经不在同一个进程中了,不会阻塞UI线程。有些app采用多进程方法,提高app的运行流畅度,但多进程用起来有一定难度,少不留神就出错了,主要原因为数据传递和共享问题。
多进程中,所谓的自定义单例模式 application 单例等等统统失效了,不能共享数据,因为没在一个进程中,所以数据处理是一个难题。
service还有一个问题,就是在绑定服务时,程序会报错,因为此时service已经是远程服务了,activity和service运行在两个不同的进程里面,传统的关联方式不适用了,所以报错。此时,一个技术就闪亮登场了,那就是AIDL。
我们可以手写一个aidl,用记事本写,像写接口一样,把.txt 后缀名 改为 .aidl即可。
 interface AIDLService {  
    int add(int a, int b);  
}
保存后,编译器会自动编译。
在上述service里面,绑定自己的bind。
    public class MyService extends Service {  
        @Override  
        public IBinder onBind(Intent intent) {  
            return mBinder;  
        }      
        AIDLService.Stub mBinder = new Stub() {  
            @Override  
            public int add(int a, int b) throws RemoteException {  
                return a + b;  
            }  
        };    
    }  

Stub是Binder的子类,所以在onBind()方法中可以直接返回Stub的实现,进行绑定。
activity中,绑定的写法和参数不变,启动的方法也一样,只需要改写一点即可,即ServiceConnection
private AIDLService myAIDLService;  
    private ServiceConnection connection = new ServiceConnection() {  
        @Override  
        public void onServiceDisconnected(ComponentName name) {  
        }  
 
        @Override  
        public void onServiceConnected(ComponentName name, IBinder service) {  
            myAIDLService = AIDLService.Stub.asInterface(service);  
            try {  
                int result = myAIDLService.add(3, 5);     
                Log.d("TAG", "result " + result);  
            } catch (RemoteException e) {  
                e.printStackTrace();  
            }  
        }  
    };  
如此,即可,其实跨进程看着也没什么难的。
以上是在自己的程序里调用,如果想让别的程序调用怎么办呢?就好把调用支付宝支付,其实就是支付宝的远程服务,封装好了,提供 .aidl文件,让我们调用。其实原理也间单
封装的service远程服务不用改写,在配置清单里,给服务的注册添加一个actiion数据,要保证这个action是独一无二的,
<service  
        android:name="com.example.cn.MyService"  
        android:process=":remote" >  
        <intent-filter>  
            <action android:name="com.example.cn.AIDLService"/>  
        </intent-filter>  
    </service>
然后再把我们编写的.aidl文件,大公无私的贡献出来就可以了,剩下的就是调用者的工作了。

在另一个程序B里,我们想调用上述的远程服务,要做几件事,首先要把.aidl文件拷到自己的项目里,注意,文件夹的名字也要与上述程序.aidl文件所在文件的名字相同。
ServiceConnection里面的写法不用修改,要改变的是启动service的方法,上述是直接启动,现在远程调用,需要用到隐式启动了,
Intent intent = new Intent("com.example.cn.AIDLService");  
bindService(intent, connection, BIND_AUTO_CREATE);
如此,完工了。跨进程通讯完成了。还有另一种跨进程的方式,是使用Messenger,好奇的可以自己搜搜。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值