Android09_远程服务_系统服务_aidl

1.1,startService()的缺陷,不能直接调用服务的代码

startService()得不到服务的引用,因为服务是框架new出来的,Activiyi里面是得不到服务的引用.如果直接new 服务类,会出错:报空指针异常,无法获取上下文,自己new出来的服务得不到上下文,也就无法打印Toast信息.(Activity也不可以直接new)

1.2, bindService()绑定服务

可以间接的调用到服务里面的方法,可以与服务进行通讯(通过代理人间接的调用服务里面的方法,直接调用可能会出现风险(篡改数据?))

1.3 通过bindService()调用服务中的方法

①创建服务的类,配置信息....

onBind()方法返回communication channel to ther service 返回服务的通讯频道,在服务成功绑定的时候返回服务中的代理人(中间人)

②创建服务的代理人:

Public class MyBinder extends Binder(IBinder的实现类)/*implements (不推荐)IBinder(会实现大量方法)*/{

创建一个方法,在方法内调用服务类的方法

}

在onBind()方法里返回中间人

③在Activity中,启动服务的时候,接收中间人

Intent service = new Intent(xx,xx);

bindService(service,serviceConnection,flags)

;Service:意图对象

serviceConnection:通讯频道

Int flags:可选的标识:一般选BIND_AUTO_CREATE//如果绑定的服务不存在,就创建它

//创建一个实现类,实现ServiceConnection

//当服务被成功链接的时候调用

onServiceConnected(xx,IBinder(获得的是服务类中return的IBinder对象));

onServiceDisConnected()

注意:在这里可以定义一个成员变量来接收IBinder对象,然后可以在别的地方使用

1.4 绑定服务,调用服务方法的步骤

在服务类中

①编写服务代码,重写onBinder对象,返回自定义的IBinder对象

②在服务内部定义一个IBinder代理人对象(内部类)

③在代理人对象里创建一个方法,间接的调用服务里面的方法

在Activity中

①采用绑定的方法连接到服务

bindService(intent,new Myconn,BIND_AUTO_CREATE)

②在ServiceConnection的实现类中有一个方法,获取到服务类返回的代理人对象

onServiceConnected(xx,xx);

③强制类型转换,把IBinder转成MyBinder类型

④调用代理人里面的方法,相当于间接的调用服务里面的方法

⑤取消绑定服务unbindService(conn对象)

注意:解除绑定的时候不能使用绑定服务new出来的conn.

2.通过接口隐藏代码内部实现的细节

①定义一个接口,接口内定义一个方法,方法名与要隐藏的方法名一致(参数一致)

②需要隐藏的类(私有的)去实现接口,通过接口把这个方法暴露出来

其实返回过来的对象,就是这个被隐藏的类的对象,但是不能直接使用这个类的对象,而要通过这个接口去接收它.父类引用指向子类对象,只能看到重写的方法.

3.绑定服务的生命周期

onBind()//绑定服务的时候调用

onUnBind()//解除服务的时候调用

onCreate()//第一次创建服务的时候调用

onStart()//已被废弃,但是还是可以用,通过startService()方法启动服务的时候调用

onStartCommand()//不会在绑定服务的时候调用

onDestory()//销毁的时候,解除服务的时候会调用

额外①:多次绑定服务,onBind(),onCreate()都只会被执行一次

②开发的时候,是不能多次绑定服务的,如果需要调用服务的方法,就绑定服务,只能绑定一次,服务只可以被解绑一次,多次解绑同一个conn对象,会抛出异常

所以绑定服务,解绑服务,就放在Acivity中的onCreate()和onDestory()中即可

4.两种开启服务方式的区别

4.1采用Start的方式开启服务

服务一旦开启,就长期在后台运行,与开启者(Activity)没有直接的关系,开启者退出了,服务还是在后台长期运行,开启者不能直接调用(可以通过广播间接调用)服务里的方法.

start开启的服务,在系统设置界面里面可以观察到正在运行的服务

4.2 采用bindService的方式绑定服务

绑定服务,如果Activity退出了,服务也会一起销毁,同时可以通过中间人间接的调用服务里面的方法

在系统设置界面里面不可以观察到正在运行的服务

额外:①取消绑定服务之后还是可以继续调用方法,是因为虽然服务被销毁了,但是服务并不会立即被回收,所以中间人的引用对象还是继续存在,所以在销毁的时候,同时要把代理人对象重置为null;

②服务如果开启的同时被绑定,那么服务就停止不了,必须解除绑定才能停止服务.

③混合开启服务的应用:为了保证服务又能长期后台运行,又能调用到服务里面的方法,采用混合的方式开启服务.

请严格按照步骤混合方式编写代码:

①start的方式开启服务(保证后台的长期运行)

②bind的方式绑定服务(调用服务的方法)

③unbind的方式解除绑定服务

④stop的方式停止服务

这样出的BUG就比较少了

要注意的是,绑定服务是需要消耗时间的(异步的),不要在绑定之后马上就调用服务里面的方法,是有可能出现空指针异常的.

5.本地服务和远程服务

本地服务(local service):

服务代码在当前应用程序的内部

远程服务: remote service

服务的代码在另外一个应用程序里

①在远程服务类里,创建类继承service,清单文件配置,过滤器定义action标签,name属性自定义

②调用者的应用中,

创建意图对象,设置setAction(保持一致)

bindService(intent,conn,BIND_AUTO_CREATE);

创建自定义ServiceConntection继承类

③远程服务类中,反馈IBinder代理人,但是想要反馈接口,在调用者的代码里并没有他.

(可不可以通过反射获取?不可以,因为内存空间是相互独立的)

5.2 重要概念

①进程:操作系统分配的独立的内存空间

②IPC:inter process communication 进程间通讯

操作系统在底层分配了一块公共空间(Binder驱动),当一方把数据放置在公共空间中,另一方就可以在公共空间中提取数据

③aidl android interface definition language 安卓接口定义语言,用于进程间通信

5.3 aidl编程

①修改接口.java文件的后缀,aidl

②不需要权限修饰符,因为都是固定public的

③gen下会自动生成对应的java文件

④本地的代理人不再实现接口,而是继承接口中的内部类(这个类是自动生成的)

⑤调用者绑定远程服务,拷贝远程的规范(接口文件.aidl,包名要一致)

⑥在绑定成功的方法中,接口名.Stub.asInterface(service)

5.4 绑定远程服务调用服务方法的流程(远程服务是运行在子线程的,不能直接Toast提示)

①跟本地服务代码编写的流程是一致的,但是不能用显示意图调用(找Class文件)而是通过隐式意图(设置Action动作调用)

②远程文件的接口定义文件,java-aidl

③把接口定义文件的访问权限全部删除,public,private

④原来的代理人extends IBinder implements 接口

现在的代理人 extends 接口.Stub

⑤调用者先把远程服务.aidl文件拷贝到本地应用程序的工程目录里,包名要一致(包名可以看做是一把钥匙,在Binder驱动空间中找到它的途径)

⑥接口引用= 接口引用.Stub.asInterface(service)得到远程服务的代理对象

⑦通过代理对象调用远程服务的方法

5.5 绑定远程服务的应用场景(远程支付)

6.1,案例,模拟支付宝安全支付练习

步骤①定义远程服务,配置清单文件action动作,重写onCreate()ondeStory()方法,定义一个方法实现支付提交的功能(用户名,密码,支付金额,账单),方法内部还有算法加密的操作,这里就不做了,也没有条件来做.最后返回数据结果

②其它操作,定义接口aidl文件,定义代理人.

③使用者,正常的远程调用服务即可.创建意图的时候不再指定classs文件,而是设置动作.再进行绑定服务的操作,其它的类同,调用方法,获取返回值.

(绑定远程服务一定要掌握,比较常见的有在索尼手机的底部有一个人脸识别的服务,可以通过绑定这个服务,把人脸的位置信息反馈至服务器.)

6.2 系统服务:

View.inflate()转换xml为view对象的操作,

底层就是调用了一个getStreamService()调用系统服务的操作.

Zygote(受精卵):安卓手机启动加载的第一个进程.

BatteryService :电池相关的服务

SensorService:传感器相关的服务

PowerManagerService-JNI:电源管理服务

PackgeManager:包管理服务

SystemServier:系统服务...........................................................................................

安卓开机的开机过程,就是一个个服务的开启.

要看安卓的源码,最好跑到内存里面观察代码的执行.然后通过内存中显示的类名查找源码.

6.3 利用系统服务监听通话的状态

①创建一个服务类,配置xml文件,重写onCraete(),onDestory()方法

②新的API TelephonyManager(这个类的实例要通过getStreamService(TELEPHONY_SERVICE)获取.)

③tm.getCallState()//获得通话状态

tm.getDeviceID()//获得入网许可id

tm.getNetworkOperator()//得到运营商的名称

tm.getNetworkType()//获得网络内容联通3G,移动3G之类

.....................

Tm.listen(listener,PhoneStatusListener.LISTEM_CALL_STATE)//电话状态监听器

④创建一个类,继承PhoneStatusListener,自定义监听器

重写onCallStateChange(int state,incomingNumer(来电电话))方法

State:TelephoneManager.CALL_STATE_IDIE //空闲状态

CALL_STATE_RINGING//响铃状态

CALL_STATE_OFFHOOK//通过状态

⑤取消监听器:tm.listen(listener,null);

⑥需要添加权限READ_PHONE_STATE

6.4 多媒体录音机的开发

①添加权限:RECORD_AUDIO,WRITE_EXTERNAL_STORAGE(保存在存储卡中)

②拷贝文档的开始,结束录音功能

修改setAudioSource(MediaRecoder.AudioResource.MIC(这个只录了你的麦克风,)为VOICE_CALL(上行下行的通话信息都录入,但是这个参数在很多手机上不生效,因为国外很多法律规定不能使用双向录音,但是华为手机支持,模拟器是不支持的))

mRecorder.setOutputStream(MediaRecorder.Outputformat.THREE.GPP)

setOutputFile(“文件名”)//SystemCLock.uptimeMills()获取系统时间

setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)//音频编码方式

注意:模拟器的音频有问题,长度有问题.

private void startRecording() {
        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mRecorder.setOutputFile(mFileName);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

try {
            mRecorder.prepare();
        } catch (IOException e) {
            Log.e(LOG_TAG, "prepare() failed");
        }

mRecorder.start();
    }

private void stopRecording() {
        mRecorder.stop();
        mRecorder.release();
        mRecorder = null;
    }

时间: 2024-11-04 06:38:42

Android09_远程服务_系统服务_aidl的相关文章

歡迎下載 高煥堂的22個視頻課程(免費)

高煥堂的22個視頻課程(免費) 目录:(视频格式:mp4) 课程(1):抽象的迷思_父类(Superclass)不是抽象出来的 课程(2):抽象的迷思_API不是从业务抽象出来的(1)_设计思维 课程(3):抽象的迷思_API不是从业务抽象出来的(2)_举例说明 请下载==>视频课程(Part_01):抽象的迷思 课程(4):从编程到设计_开发者的心灵鸡汤 课程(5):从编程到设计_A段架构师的职责 课程(6):从编程到设计_接口(Interface)与未来性设计 课程(7):从编程到设计_高老

第5章5节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 获取系统服务引用(原创)

天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文"寻求合作伙伴编写<深入理解 MonkeyRunner>书籍".但因为诸多原因,没有如愿.所以这里把草稿分享出来,所以错误在所难免.有需要的就参考下吧,转发的话还请保留每篇文章结尾的出处等信息. 上一节我们描述了monkey的命令处理入口函数run是如何调用optionProcess方法来解析命令行参数的.启动参数主要时去指导Monkey时怎么运行起来的,但Monkey作为MonkeyRunner框架的一部分,

Hacker_笔记_业内术语

参考链接: http://bbs.51cto.com/thread-623419-1.html CSRF: 跨站请求伪造 依靠用户标识危害网站 利用网站对用户标识的信任 欺骗用户的浏览器发送HTTP请求给目标站点 另外可以通过IMG标签会触发一个GET请求,可以利用它来实现CSRF攻击. 提权: 提高自己在服务器中的权限,主要针对网站入侵过程中,当入侵某一网站时,通过各种漏洞提升WEBSHELL权限以夺得该服务器权限. 提权的主要方法有以下几种: 第一 如果服务器上有装了pcanywhere服务

Android系统篇之----编写系统服务并且将其编译到系统源码中

在之前已经介绍了一篇关于如何编写简单的驱动以及访问该驱动的小程序,最后将程序编译到Android内核源码中通过程序访问驱动验证是可以通过的,那么本文就继续这个知识点,把这个驱动程序通过JNI连接创建一个系统服务,提供给上层应用访问改服务功能,可以看到前一篇介绍驱动程序的功能是属于内核层的,而本文介绍的内容是Framework层的知识. 声明:本文内容参考罗升阳的书籍:<Android系统源代码情景分析> 如果想了解更详细的内容非常建议购买此书 非常感谢罗神的这本书,给我带来很多未知的知识,大神

Android系统篇之—-编写系统服务并且将其编译到系统源码中【转】

本文转载自:http://www.wjdiankong.cn/android%E7%B3%BB%E7%BB%9F%E7%AF%87%E4%B9%8B-%E7%BC%96%E5%86%99%E7%B3%BB%E7%BB%9F%E6%9C%8D%E5%8A%A1%E5%B9%B6%E4%B8%94%E5%B0%86%E5%85%B6%E7%BC%96%E8%AF%91%E5%88%B0%E7%B3%BB%E7%BB%9F%E6%BA%90%E7%A0%81/ 在之前已经介绍了一篇关于 如何编写简单的

Android系统篇之----免root实现Hook系统服务拦截方法

技术概念来源:[ 360开源插件框架,项目地址:https://github.com/DroidPluginTeam/DroidPlugin ] 一.Binder机制回顾 在之前一篇文章中介绍了 Android中的Binder机制和系统远程服务调用机制,本文将继续借助上一篇的内容来实现Hook系统服务拦截指定方法的逻辑,了解了上一篇文章之后,知道系统的服务其实都是一个远程Binder对象,而这个对象都是由ServiceManager大管家管理的,用户在使用系统服务的时候,会通过指定服务的Stub

Android系统篇之----Binder机制和远程服务调用机制分析

一.前景概要 最近要实现Android中免注册Activity就可以运行的问题,那么结果是搞定了,就是可以不用在AndroidManifest.xml中声明这个Activity即可运行,主要是通过骗取系统,偷龙转凤技术的,这个知识点后面会详细讲解的,因为在研究了这个问题过程中遇到了很多知识点,当然最重要也是最根本的就是Android中的Binder机制和远程服务调用机制,而关于Binder机制的话,在Android中算是一个非常大的系统架构模块了,光这篇文章是肯定不能讲解到全部的,而且本人也不是

python基础教程_学习笔记20:标准库:一些最爱——os

标准库:一些最爱 os os模块为你提供了访问多个操作系统服务的功能. os和它的子模块os.path还包括一些用于检查.构造.删除目录和文件的函数,以及一些处理路径的函数. os模块中一些重要函数和变量 函数/变量 描述 environ 对环境变量进行映射 system(command) 在子shell中执行操作系统命令 sep 路径中的分隔符 pathsep 分隔路径的分隔符 linesep 行分隔符('\n','\r','\r\n') urandom(n) 返回n字节的加密强随机数据 os

设计模式(2)_代理模式 ————— 控制对象访问

设计模式(2)_代理模式 ----- 控制对象访问 一.动机 需求 现在有这样一个需求:有一个出版社,该出版社有一个工厂,专门用来生产制造图书,该工厂里有很多台生产制造图书的机器.每个机器有自己的位置坐标,用 int表示,机器的状态,{正在工作,暂停,故障},已经印刷了多少页图书.在出版社 在工厂 厂长的电脑屏幕上,可以随时打印出任何一台机器的报告信息(report infomation). 下来 我们用代码实现这个需求: PrinterMachine.java package com.crg;