说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

从友盟微社区看Android第三方SDK架构实践

HTML文档下载 WORD文档下载 PDF文档下载
第三方SDK的开发需要考虑很多因素,比如稳定性、灵活性等,并且还要做到能让开发者能自由定制UI层、替换子系统。本文以友盟微社区为例,详细讲解了在开发SDK时架构方面的设计理念。

开发Android第三方SDK说难不难,但说简单也不简单,要开发一个给很多人使用的第三方SDK,如何在保证稳定性的同时,增强SDK的灵活性,让开发者能自由定制UI层、替换子系统,这是一个值得思考的问题。为了解决这个问题,开发第三方SDK必须要有良好的应用架构。本文就分享一下我在开发友盟微社区SDK时在架构方面的一些想法。

友盟的微社区是一款帮助开发者在应用中快速搭建一个社区(类似于新浪微博、朋友圈),目前正在内测当中。

技术架构

从项目结构上来说,友盟微社区SDK可以简单分为如下三层。

  • UI层(开源)。UI层对外开放,目的是让用户能够定制微社区的UI效果,使微社区SDK能够很自然的融入到用户的App中。
  • 业务逻辑层。业务逻辑层会通过一个统一的接口向UI层提供数据请求等功能,比如获取缓存的feed、好友列表等,因此业务逻辑层对于用户来说是一个数据操作接口,通过这个接口用户能够与SDK核心层进行一些数据方面的操作。
  • 核心层。核心层则包含了友盟SDK的核心系统抽象,比如账户系统、推送、数据库、网络操作等,这一层对外封闭,用户可以通过一些接口与核心层进行交互。而核心层定义的抽象使得用户可以很方便的实现定制化,即自己实现抽象接口,然后将具体的实现注入到微社区中,从而使自己的子系统替换掉微社区中的默认实现。

如图1所示,SDK层次非常分明,通过这三个层次的隔离,使得用户既可以自定义最外层的UI效果,也对外隐藏了业务逻辑层、核心层的实现细节。而核心层定义的子系统抽象,使得用户可以注入自己的实现,保证了整个微社区SDK的灵活性、扩展性。

图1 洋葱结构图


简单来说,就是用户在UI层通过逻辑层暴露的通用接口来操作SDK,从封闭的核心系统中获取、存储数据以及其他的相关操作。层次结构如图2所示。

图2 层次结构图

图1、图2都显示了SDK是通过不同的层次来分离职责,是一个较为典型的架构形式。对于用户来说,最关心的莫过于可定制化。UI层开放源码,自然可以通过修改代码来实现。其他的定制化用户就需要依赖注入来实现。微社区SDK内部依赖于抽象,而不依赖于具体实现,并且用户可以注入具体实现。也就是说用户可以根据我们的抽象接口实现自己的子系统,然后注入到SDK内部,SDK此时就会使用用户注入的实现,这样就达到了子系统替换的效果,也就是我们说的定制化。

友盟微社区的定制化

如何满足定制化?

那么如何来实现定制化呢?友盟微社区SDK内部定义了一些抽象,比如Loginable、Pushable、ImageLoader来分别代表登录系统接口、推送接口、图片加载接口,每种接口都有一个SDKManager来进行管理。比如管理登录子系统的就是LoginSDKManager,用户可以往这个Manager里面添加、移除具体的登录系统实现,然后通过useThis函数来指定使用某个具体的实现(SDK Manager里面可能有多个实现)。结构图如图3所示。


图3  LoginSDKManager功能

SDK Manager是一个泛型类,类型T就代表了接口类型,比如上述的Loginable等。通过泛型我们就可以将这些通用的添加、移除实现等操作抽象化,避免重复代码。代码如下所示:

public abstract class SDKManager<T> {

  //泛型Map

 private Map<String, T> mImplMap = new HashMap<String, T>();

 // 要使用的实现的key

 private String mCurrentKey = "";

 public void addImpl(String key, T impl) {

 mImplMap.put(mCurrentKey, impl);

  }

 public void removeImpl(String key) {

 mImplMap.remove(mCurrentKey);

  }

 public void useThis(String key) {

 mCurrentKey = key;

  }

 public T getCurrentImpl() {

 return mImplMap.get(mCurrentKey);

  }

}

代码很简单,就是在SDK Manager内部维护了一个Map,key是用户为这个实现指定的一个字符串值,value就是具体的实现。用户可以通过这个key来移除实现,更常用的是我们需要调用useThis(String key)接口来指定使用某个具体的实现。 

我们并没有直接使用SDKManager,因为它是一个抽象泛型类,因此我们定义了一些子类来对不同的实现进行管理,这些子类都是单例类,例如LoginSDKManager,代码如下所示。

public final class LoginSDKManager extendsSDKManager<Loginable> {

 // 单例对象

 static LoginSDKManager sInstance = new LoginSDKManager();

 private LoginSDKManager() {

  }

 // 获取单例对象

 public static LoginSDKManager getInstance() {

 return sInstance;

  }

}

在用户需要对登录系统进行管理时,通过LoginSDKManager.getInstance()就可以获取到负责管理登录系统的SDKManager,此时用户可以通过addImpl(String key, T impl)、useThis(String key)等接口对登录系统进行管理,这就可以灵活使用用户自定义的子系统。

示例

下面还是以一个示例来说明问题吧。在与用户沟通的过程中,我们发现登录模块是用户自定义概率最高的子系统。通常情况下,用户可能有自己的账户系统或者使用了第三方登录,此时用户就不需要友盟微社区SDK中附带的登录实现,完全依赖自己的账户系统或者其他第三方登录SDK来实现一个登录系统。下面我们就以实现登录系统(其他子系统的自定义原理一样)来演示自定义过程。在开始之前,我们需要对登录的抽象接口Loginable进行了解。代码如下所示:

public interface Loginable {

 public void login();

 public void logout();

 public boolean isLogined();

}

  • login():登录函数,用户需要在登录成功后将用户信息回调给友盟微社区SDK(具体过程可以参考友微社区集成文档http://dev.umeng.com/wsq/android/detail-integration#1);
  • logout():登出函数,注销用户的登录即可;
  • isLogined():用户是否登录,返回true表示已登录,否则为未登录。

微社区SDK内部通过抽象了几个简单接口来定义登录模块的功能,用户通过实现这几个函数即可定制自己的登录系统,最后将实现注入到SDK即可。例如,如果你的应用中已经有了自己的账户系统逻辑,你可以在Loginable的几个函数中通过调用你的账户系统逻辑实现这几个功能;如果你使用了友盟社会化组件那么你可以通过该社会化组件的登录、登出功能实现对应的功能,例如你可以在login()函数中调用UMSocialService对象的doOauthVerify(Context context、SHARE_MEDIA platform、UMAuthListenerlistener)接口来实现登录。

一句话概括就是:自定义一个实现了Loginable接口的类,在这个类的各个函数中调用你原有的登录、登出、判断是否已登录的函数来实现对应的功能。实现了登录类之后,通过LoginSDKManager的addImpl(String key, Loginable impl)来将该实现注入到SDK中,最后通过LoginSDKManager的useThis(String key)函数来指定要使用的登录实现,这个key就是addImpl(String key、Loginable impl)中设置的key。

自定义登录类示例代码如下:

/**

* 友盟社会化组件的登录实现,这里可以替换成自己的账户系统、第三方登录等,实现几个接口函数即可。

*/

public class SocialLoginImpl implementsLoginable {

 @Override

  public void login() {

 // 登录的具体实现,可以调用你自己的登录代码或者第三方SDK的登录函数

  }

 @Override

 public void logout() {

 // 登出的具体实现,可以调用你自己的登录代码或者第三方SDK的登录函数

  }

 @Override

 public boolean isLogined() {

 // 检测是否登录

 return true /* 代码省略 */;

  }

}

**注入登录实现 :** 

// 登录系统管理器

LoginSDKManager loginMgr =LoginSDKManager.getInstance() ;

// key

String clzKey =SocialLoginImpl.class.getName() ;

// 注入实现

loginMgr.addImpl(clzKey, newSocialLoginImpl());

// 指定使用的具体实现

loginMgr.useThis(clzKey);

为了更简单,这个过程被我们封装到一个函数中,使用的代码最后简化为 : 

// 一行代码搞定!这个函数封装了上述所有的代码。

LoginSDKManager.getInstance().addAndUse(newSocialLoginImpl()) ;

通过这几步,登录系统就被替换掉了。当微社区需要登录时,微社区SDK就会通过LoginSDKManager获取当前使用的登录实现,然后触发login()函数,此时就会执行你的登录代码了。登录成功之后,通过login()函数的回调listener(这个简单示例中没有给出该listener,具体可参考友盟微社区使用已有账户系统)将用户信息传回给友盟SDK,就完成了整个登录过程。

目前友盟微社区SDK还处在内测阶段(内测申请地址:http://wsq.umeng.com/),不过已经可以投入使用。已经有一部分集成了友盟微社区的App上线,并且运行良好。希望本文能有开发第三方Android SDK的同学一些帮助,让开发中的坑更少一些。

本文作者:何红辉,Android工程师,现任职于友盟。乐于分享,热爱开源,开源项目有AndroidEventBus、android-tech-frontier、Android源码设计模式分析。

CSDN博客:http://blog.csdn.net/bboyfeiyu,GitHub
主页:https://github.com/bboyfeiyu


VB用EXCEL组件简化VB编程的一种方法 VB用MDB文件做密码库 VB用ODBC API访问ODBC数据库 用VB 实现类电子表格的数据录入 用VB5直接控制Excel 97 用VBA编制Access的查询程序 用VB和RDO访问SQL Server 用VB开发多通道仪表数据采集程序 用VB实现关闭所有数据库对象 用VB实现类电子表格的数据录入 VB用代码创建数据库,表,字段 VB用类来编写数据库程序 优化OLE的调用频率-VB资料 语言选择引起的查询错误 -VB资料 远程数据库的访问-VB资料 运用ADO进行数据库表数据互导 -VB资料 在 VB5.0中编辑数据库和电子表格 在Access 2000中用ADO-VB资料 在Access数据库中实现密码管理的另一种方式 -VB资料 在VB6.0中使ACCESS数据库在网络使用中保持同步 在VB中更改SQL Server数据库结构 在VB中兼容非ACCESS数据库的技巧 在VB中引用dbf及索引文件 在VB中运行Microsoft Access报表的好方法 在VB中直接用ODBC API访问数据库 在数据库应用中, 经常要动态生成 Select 语句,典型的情况:-VB资料 在运行时修改DataEnvironment的连接字符串-VB资料 在抓取資料庫之資料前先計算資料總筆數 -VB资料 增加 MsFlexGrid 的编辑功能-VB资料 真正删除数据库的记录 -VB资料 用VB制作屏幕保护程序 请教新手问题~~~麻烦哪为大侠给解释解释~谢~ 如何用struts实现阴阳色列表? 怎么用vb建立一个数据库呀?注意,不是一个表,是一个数据库! 如何调用系统默认打印机的属性! 一个很老很过时的数码相机。 郁闷,超级简单题目 初学ASP,请教学习心得 我的机器怎么老死机?? 两级表单动态联接?急,急,急!!!!!????? ---见了鬼了,Jre不好用!!!--- 寻求把中文字符串转换为十六进制的串的ORACLE函数? 电力学院惊魂 一條語句 數據庫日誌就寫滿了 怎样获得系统的字体!急!谢谢了! 谁有用java做的聊天系统程序(当作业)分不够可再给 在CB中如何动态的管理窗体 如何调用系统默认打印机的属性! API动态调用问题(很奇观) 好久没有发帖子了,现在心情奇好,兄弟们来接分! 在CB中如何动态的管理窗体 求C#网络编程书籍下载~ 简单问题,在线等待。可以在加分。 请教一题目! thanks sdany java 中能不能实现一个数字键盘 关于重定位 菜菜问题:让VB画出sin(x)和log(x)的函数图象怎么做?刚学VB的,x可以取任意的值! thanks sdy 模拟鼠标键???? 弱智问题,请原谅 我需要帮助~~~~!!!!! 请教:用LoadImage()载入的光标资源,当光标尺寸大于32*32时,显示不正常? cls 怎么用??? 请问<%=type2(RS("qi_type2"))%> 是什么意思? 招ASP程序员,工作地点杭州. ORACLE9i中的storage怎么不起作用了? 评评<<离散数学及其应用>>.我有些题目不会做呀.比如和费马小定理有关的.呵呵 谁能告诉我程序员考试是每年的什么时候啊?? 声音设备问题? 关于字符串输出 利用VB写SQL语句的问题(实现删除功能) 太岁灭城 晋中鬼事之二 (书雅) 有关上传数据库的问题? asc码为13的在jsp里用什么表示? GetCurSorPos声明在哪里? 信誉值怎么升高?怎样提高可用分?我的分太少了! help:中文字段update出错 用VB写SQL语句实现删除功能的问题。 请问怎么发布带有Query组件的odbc引擎的activex程序?急 EXCEL里某一行的行高是100,这个100是什么意思? 有没有办法调试delphi控件的源代码? 霞霞不听话好看的繁体字 求具体过程及答案 题目是这样的 一辆汽车的发动机的额外功率为6*10^4W 水平面匀速行驶受到的阻力是1800N 在额外功率下 当汽车匀速行驶时 求:1 发动机所提供的牵引力大小?2 行驶速度的大小?3 行驶5min牵引力 The man had had an uncomfortable trip.He was very hungry.(not only……but……as well)用括号中的连词改写上面的句子,具体说啊, 支离破碎这个词语有什么样意思!代表什么!它的意思 已知数列an的通项公式为an=以(n+1)为底(n+2)的对数.则它的前n项之积为? 画一张画,和一篇作文! 急死了不知道到明天晚上有没有回答,所以先放20分,有人回答,并且我满意的加50!言归正传,我所学的是哲学基础知识(第二版),高等教育出版社的.都是辨析题,然你说明下面的是否正确.1:追 为什么当车轮高速运转是你会觉得它是在倒转? the man had had an uncomfortable trip.he was very hungery (not only-but-as well)he had not eaten anything for thirteen hours.he had not drink anything for thirteen hours(neither-nor)wollen goods cannot be eaten.at least they are soft.the man had had 二 马克思主义哲学产生的自然科学前提有(  ) (5.0 分) 能量守恒和转化定律 达尔文生物进论     康德星云假说     细胞学说     2.费尔巴哈唯物主义哲学的主要缺陷有( 德语复数的若变化动词是不是都变成-en? 假如说我今天用望远镜看见10E光年一个星球爆炸,那是10E光年钱的事情吗? modest dividend是什么意思 芒山盗临刑 一物生来真奇怪,它是世界一盘菜,娘死以后它才生,它死以后娘还在.(打一微生物) 哲学基础作业00081.划分唯物主义和唯心主义的唯一标准是( ).A.对思维和存在何者为第一性的回答B.是否承认世界只有一个本原 C.有否高尚的理想D.是否信仰上帝或菩萨 满分:2 分2.现代科技 德语里边阳性名词的第四格为什么要加en呢?那第三格要不要加,复数要不要加? “一切恩爱会,无常难得久.生世多畏惧,命危于晨露.因爱故生忧,因爱故生怖.若离于爱者,无忧亦无怖. dividend smoothing是什么意思 这个田野花是什么花.如题 由爱故生忧,由爱故生怖.若离于爱者,无忧亦无怖. 美国独立战争介绍 一年级语文下册田野里开的都有什么花 求求你们了一根电阻丝的电阻为R=16欧姆,将他做成正方形求(1)A B两点间电阻R AB为多少欧姆?(2)AC两点之间电阻RAB为多少欧姆? 什么是支离破碎? 汽车快速经过栏杆时,越过栏杆看车轮,为什么看上去倒转或停止 假如战斗机在飞行当中突然爆炸,此时的飞行员没有来得及跳伞,那么这个飞行员还有没有生还的可能了?XIE XIE HUI DA. 要详细过程和答案,谢谢啦! 第一次世界大战对主要资本主义国家有什么影响 be early和early有意思和词性上的区别吗be early是短语吗?是固定搭配吗?---------------------------------He is always early for workHe always finish homework early上面两句表述都对吗? 有关光电效应的一个问题什么是光电效应的阻遏电位(即stopping potential)啊?谁能给解释下. 求解答,要详细过程,谢谢! 如何通过实验确定各转录因子的功能? 小丽每分钟跳绳160下,小李每分钟跳的数量比小红少九分之一,比小华多七分之一.求小红和小华每分钟各跳多少下 多项选择,本大题共10个小题,每小题 4.0 分,共40.0分.在每小题给出的选项中,有一项或多项是符合题目要求的.1.下列命题中属于主观唯心主义的有:( ) A.物是感觉的复合B.宇宙便是吾心,吾心 诺曼底号遇难记读后感300字,急 bonus和dividend的区别?请不要复制词典的内容!最好给出一些例子来, 方程组2x+3y=k,3x+5y=k+2,中x与y的和为12,求k 2 3小题,写纸上,先答先采纳, 如何区分INTEREST的两种意思INTEREST什么时候表达利益的意思,什么时候表达兴趣~以前老师也说单复数,但我在书上看到一句不同的兴趣是"DIFFERENT INTERESTS".对了,还有,表达兴趣的INTEREST一定是不可 英语翻译:谁知道:Dividend equivalent did you leave the park early yesterday afternoon?no,I__there___it was closed.A left;before B stayed;until C was staying;after D was leaving;until dividend与divedent的区别equals 与equal,equation的区别 ( )田野里( )盛开着( )鲜花 日记快 可变成本与不可变成本的含义 课程的名子叫做《毛泽东思想、邓小平理论和“三个代表”重要思想概论》!就是我们平时说的“毛、邓、三”.作业的要求是这样的:字数1500字左右!大标题:中国特色社会主义建设的关键--- 韩式如何画眉毛 固定成本和可变成本的问题当产量增加时,单位产量上摊销的固定成本就会减少,而可变成本不发生变化,其总成本将减少? ()在田野里()盛开着()的鲜花 关于光电效应的一道题“若激光束射入玻璃球之前能使某种金属发生光电效应现象,通过玻璃球时由于有能量损失,穿越玻璃球后射出就有可能不能使该金属发生光电效应现象”这句话为什么 以下哪些是可变成本,哪些是固定成本?外购原材料,外购燃料及动力,工资及福利,修理费,折旧费,摊销费,财务费用,其他费用哪些是可变成本,哪些是固定成本?如果折旧和摊销都采用直线折旧法 大学物理实验数据处理问题 测量值是,200.5.不确定度是0.04.求实验结果该怎么表示? 霞用韩国文字怎么写 总成本包括固定成本和可变成本, 一道物理题-关于汽车的汽车在加速的时候受的是平衡力吗?还有在功率一定的条件下 P=F牵引·V 那么汽车的牵引力和摩擦力是一对平衡力吧汽车的摩擦力大小没变 汽车走动不是靠二力平衡吗? 天上的彩虹,什么万丈,好看极了.用霞组词 支离破碎的意思 一道物理题,关于车的= =!甲乙两列火车,甲长120米,乙长80米,两车同向行驶时的超车时间为40秒,两车相向行驶时的错车时间为8秒,如果甲快乙慢.求甲乙两车的速度各是多少?PS:要有过程啊...最好 河北宣化女村官称遭官员性骚扰 出示微丝绸之路国际大会在伊斯坦布尔举行伊朗就核问题对话提出新建议内蒙古国贫旗现豪华接待中心 回应称为25省区市前三季度GDP之和超全国总专家称当代难谈“汉字危机” 呼吁重视“今日中国”艺术周系列活动在泰国举行西班牙煤矿瓦斯泄漏致6人死亡印度央行下调经济增长预期企业被强拆讨说法遭踢皮球 对方扬言:美国在罗马尼亚反导基地开工建设孟全国大罢工第二天又有4人死亡长兴废旧铅蓄电池“涅槃重生” 废水处粤高院判美IDC公司构成垄断 赔偿华俄外长:俄愿意与美国就反导问题寻找折约40名尼日尔移民因汽车抛锚在撒哈拉北海道频现“熊出没”都是橡树减产惹的日本滋贺县调查显示老年人受虐情况多来古老东京车站鲜花生气勃勃 花团锦簇画俄官员:与中国免签证旅游交流能避免非英国男子涉嫌侵入美政府计算机系统遭逮垃圾分类要普及,财政补贴须跟上市民车检有问题 打支队长手机投诉[我财经]全国每年人事档案收费数十亿“广州眼”能不能点赞,取决于谁出钱建雪花秀洗面奶细菌超标大学生档案开寄 办手续需带通知书、准三轮车专属位 小车司机莫“占座”大熊猫三胞胎广州诞生新扩改建房屋先押10元/平方米“新型青少年频发溺水 巡逻车配救生衣产业整合与资产注入成并购主流天然气价格完全市场化渐行渐近微生活美国变性夫妇生下两子 丈夫生子妈妈当荔湾儿童公园10月开放价格型调控非“中国版QE”经济日报:下好制造业服务化这盘棋家乡旱从何处来?恒大更换意大利球探俄部队前往蒙古参加双边联合军演 将使“依法治国”容不得“夜半强拆”
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘