Android sdk开发教程 oppo首席架构师手把手3分钟教会你

1.sdk的架构设计

2.sdk的初始化 集成和编译,配置流程

3.sdk的appkey 安全问题,混淆

4.sdk的升级,日志分析,性能分析

什么是SDK

SDK是Software Development Kit的缩写,译为”软件开发工具包

SDK实现目标

高效

无论是普通的应用开发还是SDK开发,都应该考虑到性能问题,SDK设计者应该着重考虑以下问题:

更少的内存占用.在不使用多进程的情况下,SDK服务和宿主程序运行在同一进程中,这种情况下必须要求限制SDK内存的占用,不能因为说因为我们SDK占用太多的内存资源,导致应用的存活时间变短.

更少的内存抖动.在占用更少内存的前提下,SDK设计者必须刻意的减少反复GC造成的内存抖动问题.

更少的电量消耗.尽管很多时候无法对电量消耗做一个很好的权衡,但是仍然有一些可以参考的做法,比如减少使用耗电模块的时间.比如在使用定位服务时,不要求非常高的精度下优先使用网络定位而不是GPS定位.

更少的流量消耗.

SDK整体架构设计

SDK的架构实现决定了SDK后续的维护难度,因此有必要在此对SDK整体架构中的一些点做些简单的说明.

 

SDK的架构实现决定了SDK后续的维护难度,因此有必要在此对SDK整体架构中的一些点做些简单的说明.

 

模块化开发

 

根据单一职责将系统拆分为不同的小模块,每个模块保持相对独立。

模块之间通过协议或接口通信,以减少相互之间的依赖耦合.模块内部按照设计的几大原则进行实现,以保证模块本身可以灵活实现

对于现代开发而言,模块化是常用的手段,从宏观角度来看,模块是系统最小的组成单元.

 

组件化开发

 

组件开发同样是个老生常提的概念,但从我个人的感受来说,组件是对逻辑的封装,并具备单个可移植性.比如可以把日志记录做成一个组件,之后它可以被轻松在应用在不同的项目中.对于android 开发者而言,Android 提供的每个UI 控件同样也是组件,比如Button,TextView等.

 

在明确了组件这一概念之后,组件化开发也就不难理解:所谓的组件化就是将整个项目划分成多个模块,几个模块或者单个模块作为一个组件,开发过程中我们可以对每个组件进行并行开发,最后发布时通过依赖将组件合并成完整的应用.

 

那为什么要使用组件化呢? 

随着android的逐渐成熟,现在的app业务越来越复杂,与此同时,android工程也变得日益庞大,代码行数十几万已经是常态,此时有几个问题便会凸显出来:

 

工程任何一点改动都会造成整个工程的重新编译.记忆最深的就是早期在没有进行组件化的时候,庞大的工程动辄需要十几分钟的编译时间,一杯茶的时间就出来了,很多时候,不得不眼巴巴的等着,尽管现在可以使用facebook出品的buck以及来自阿里的feeline来加速编译过程,单仍然不够.

整个工程中充斥的大量重复或者冗余的子模块,业务耦合度非常高,牵一发而动全身.这就造成了”老人不敢改,新人无法改”,因为谁也不能预知在做修改之后,会产生什么影响.

协作开发基本上是不可能的,天知道彼此在做什么.代码合并的的时候更是令人痛苦.

不方便测试.高度耦合的业务和模块导致无法下手进行测试,只能草草了事.

通过引入组件化,上面遇到的问题便可迎刃而解.在SDK当中,根据实际情况对其进行组件化,比如我们将分享功能组件化,可以轻松的支持多种渠道的分享,在需要更新分享功能时,可以对其进行单独的编译和测试.

--------------------- 

插件化开发

 

什么是插件化开发这里就不做介绍了,一方面插件化并不是个新概念,另外就是插件化到目前为止理论层次上已经非常成熟,不想15念开始研究的时候资料相对较少.

 

在SDK中为什么使用插件化呢?SDK不同于普通应用,不能频繁的进行更新,以免让开发者觉得SDK不稳定或者让开发者频繁的集成.SDK看起来变化较慢,实则变化频繁.就以以前做的广告SDK而言,有时候经常需要对某类机型进行数据采集或者及时更新反作弊模块,在没有使用插件化之前,解决该问题是非常麻烦的.但是在我们利用插件化之后,解决该问题就变得非常容易:我们将SDK整体划分为两部分:宿主和插件.宿主只向开发者提供必要的服务接口,并提供了自定义插件加载器.而核心的逻辑则是存在于插件中.当需要采集数据的时候,只需要由开发人员开发好数据采集插件并下发到指定设备即可;当需要修复SDK缺陷时,同样也只需要下发新的插件包即可.

通过在SDK使用插件化方案,可以有效的对开发者屏蔽手动更新的过程.宿主相对稳定,一旦确定,一般不会变动,而后续的业务变化则只需要通过更新插件来支撑.

除了上面谈到的利用插件化解决动态更新之外,通过将整个工程分为宿主和插件可以实现宿主的并行开发和分开编译,并且能有效的解决方法数65535的限制.在没有使用插件化之前,我们整个项目是由很多组件通过依赖形成的庞大工程,不得不通过

--------------------- 

 

SDK初始化

和应用开发不同,很多情况下SDK没有自身的上下文Context,而必须要借助应用提供.SDK初始化的常见做法:Ad.init(Context context,AdParams params)

 

安全

 

1.SDK自身安全

为了区分接入者并挑高SDK自身安全性,我们通常会为开发者分配api key和api secret,SDK会读取开发者配置的api key和api secret,并用于随后的网络通信中.这是非常常见的做法,比如当你集成极光推送SDK的时候,它也许需要你提供api key和api secret,如果没有则需要到官网进行申请.

 

2.核心逻辑采用C/C++

 

为了安全起见,数据加密类,模块算法类都都应该采用NDK开发,将其封装在so文件当中.有很多开发者不明白为什么这样会增强安全性.这里我们简单的做个说明.由于.so文件是通过c/c++编译出的文件,相对于java的反编译文件来说,可读性更差,另外大部分的Android开发者并不具备较深的C/C++能力,因此一定程度上增加了被破解的能力.

 

3.通讯加密

 

针对实际情况对通讯协议进行加密,具体是采用对称加密还是非对称加密,则需要根据实际情况做选择.另外,请尽可能使用https来代替http.

 

3.设备安全

 

在很多情况下,比如广告SDK中,有一些开发者会通过虚拟机来刷广告,因此有必要针对此情况做判断.一旦SDK检测出非法请求后可以采取两种方案,一种是SDK拒绝服务,另外一种则是正常服务,SDK会将作弊信息上传至服务器,以便后端服务定向排除数据.

 

4.减少传输数据大小

 

在设计SDK和服务端通讯之间的数据协议时,需要根据实际情况考虑,但有以下几条建议值得我们接受:

如果对传输的数据大小有要求,建议对数据进行压缩.

可以采用json/xml/Protobuf等协议,如果它们仍然不能满足则可以考虑自定义二进制协议.

 

5.选择支持最低系统版本

 

作为SDK的设计者,面临一个很大的问题是我们不得不考虑开发者应用所支持的系统最小版本,但是在SDK发布之前,我们并不知道会什么样的开发者使用我们提供的服务,因此为了让SDK支持更广泛的设备,我们需要降低最低支持的系统版本.比如现在失眠上主流的系统版本是Android 5.0,那么对SDK而言,起码要支持到Android 4.0,甚至是Android 2.3.

 

降低最低支持版本看起来很容易,但是我们不得不做更多的工作来确保SDK能表现出一致的工作行为(通常,我们在SDK内部检测当前系统版本来确定哪些方法可以被调用).更残酷的真相是我们花费了很大的精力去支持2.3,但来自2.3系统版本的请求量却连1%都不到.

 

6.权限管理

 

Android中任何开发都避不开权限申请.作为SDK的设计者,对于权限遵循”如无必要,无需增加”,换句话说就是用不到的权限,就不要加上去,这也是我们所谓的最小权限原则,该原则同样适用于普通应用开发.

在刚接触SDK开发时,某些早期功能需要某些权限,但是后期该功能被砍掉了,但是权限却忘记去掉,这就导致不必要权限仍然存在的情况.

另外过多的权限申请,会让开发者怀疑你的目的.比如一个广告SDK的你申请照相机权限是想干嘛?恩,我怀疑你在偷拍我….好吧,这里我只是开个玩笑.

另外,从android 6.0以上,google改变了权限申请的策略,因此需要单独对此做适配.

 

日志服务

 

无论系统大小,日志服务是基本的服务.一个良好的日志服务能够帮助我们快速的发现问题,定位缺陷,从而获得问题的解决方案.

 

SDK的日志服务和其他常见的日志服务并无太大的不同,但是要保证以下几点:

日志服务能够记录有效的信息,在SDK要关键位置进行打点.

日志服务上传日志信息到服务器时,要保证最大的可靠性,不能发生上传失败后抛弃日志的情况.

日志服务不能影响对正常的操作流程有过多的性能影响.SDK产生的日志信息往往是非常多的,因此必须考虑日志IO操作所带来的开销.

 

一、配置清单

1、AndroidManifest,若SDK在配置清单中申请权限,编译时就会报合并重复错误,只能去除主项目中原有的声明。因此,不建议在SDK内部声明,应改为在接入文档中说明,由主项目配置。

2、<application/> 标签,常见默认属性如:android:nameandroid:themeandroid:lable... 如无切实必要,请去除这些属性,避免打包时与主项目冲突。

 

3.在android studio上可以开发jar(java通用类库)和aar(android 独有资源库)。

 

     区别:    

 

        *.jar:只包含了class文件与清单文件,不包含资源文件,如图片等所有res中的文件。

 

        *.aar:包含所有资源,class以及res资源文件全部包含

4.资源id命名规范

Values中的colors、strings、styles中的id命名应当注意保持一定的唯一性(如:命名统一加项目前缀),避免与主项目中的资源id冲突,造成SDK中的资源被覆盖,如theme、string等等。

当然,从另一个角度来看,这个特性也可以作为定制UI的一个思路,用主项目中定义的相同资源覆盖掉SDK中的资源属性,从而实现灵活改变SDK的样式。


 

5.混淆问题

在Android开发中,我们一般都会对代码进行混淆后发布,所以在测试SDK时必须考虑到这个情况。

默认情况下,proguard-rules.pro中的混淆配置是不会被打包进aar中的,所以一般需要在主项目中手动指定混淆规则。

但是,为了提高接入体验,能否将SDK中的混淆配置也打包进aar中,让项目自动配置SDK的混淆文件呢?答案是肯定的,我们可以指定consumerProguardFiles属性,自定义引入的混淆规则,即可将*.pro文件打包进入aar中,项目打包时就会自动合并该配置文件。 值得一提的是该属性只镇对library有效,对app无效。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值