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中。
把一个本地服务变成远程服务,很简单,在配置清单里面,服务配置的节点里,添加  即可。
我们重新点击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是独一无二的,
        android:name="com.example.cn.MyService"  
        android:process=":remote" >  
         
             
       
 
   

然后再把我们编写的.aidl文件,大公无私的贡献出来就可以了,剩下的就是调用者的工作了。

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

更多相关文章

  1. Android里解析AndroidManifest.xml的java文件
  2. Android(安卓)IPC 通讯机制源码分析
  3. activity中onSaveInstanceState方法调用时机详解
  4. androidTV 9.0 开发调用系统jar异常报错,jar引用已导入还是报错,分
  5. Activity启动过程分析
  6. android UI线程安全问题
  7. 给学android的同学们的一些建议【III】
  8. android 温故知新之fragment中易忽视的onViewStateRestored()
  9. Android完全退出应用程序

随机推荐

  1. 如何修改Android应用程序能够使用的默认
  2. Android移动应用基础学习——第一章基础
  3. Android2.3 中如何使用GPU硬件加速
  4. Android中实现网络图片的获取
  5. Android面试题精选
  6. Android学习之ION memory manager
  7. Android应用开发学习之相对布局
  8. 简单的Android对文件进行读写操作
  9. Android内存之VSS/RSS/PSS/USS
  10. 2011.10.09——— android ImageView放大