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

从友盟微社区看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


如何查阅可视窗口标题-Delphi资料 如何得到Timage控件的DC-Delphi资料 如何关闭一个MDI子窗口-Delphi资料 如何检测鼠标击了哪一个对象-Delphi资料 如何将鼠标锁定在固定范围内-Delphi资料 如何使你的窗口Stay on Top-Delphi资料 如何在ListView控件中绘底图-Delphi资料 如何在屏幕上移动Image图象-Delphi资料 软件中复活节彩蛋的实现-Delphi资料 实现图象局部放大的原理和方法-Delphi资料 使用Delphi实现滚动式面板窗口 通用的MsgBox-Delphi资料 图象放大镜——实现图象局部放大的原理和方法-Delphi资料 图形的特殊显示效果-Delphi资料 图形整体拉出效果-Delphi资料 一个实用的Delphi屏幕拷贝程序的设计 用Delphi 显示122种图形特效 用Delphi编写DLL实现动态改变分辨率 用Delphi进行OpenGL编程学习心得 用Delphi开发windows95屏幕保护预览程序 用Delphi实现壁纸更换 用DELPHI实现位图显示特技 用DELPHI中Canvas特性开发图形软件 用构件变换法实现动画效果-Delphi资料 在Delphi中使用动态图标 在Delphi中显示Windows图标 在多媒体文件中批量抓取图象-Delphi资料 怎样读出不同格式图形的高和宽-Delphi资料 怎样使用PageUp、PageDown滚动窗体-Delphi资料 怎样制作全透明的窗口-Delphi资料 DELPHI:FormContainer简易手册 请大家推荐一个方便好用的网格控件,可以编辑、保存单元格的内容,bug又少的 急死我了,这行SQL语句错在那里呢? ORACLE8I安装问题,急。。。。。。 还是这两本书110分 急救:主板CMOS故障!! 有谁知道在JBuilder中插入一副图片应该用哪个Compoent 加急问题??关于.properties!!在线等, Win2K下控制台程序处于选定状态,如何恢复? 窗口自动关闭 救命啊!严重问题!怎么老是显示E2316:TempSongList::PlayFirstSong()is not a member of 'TempSongList'? 关一个小笨蛋生存的困惑,还请各位GG、JJ一定要帮帮忙呀~~~~ Interface中添加方法的问题,请高手指教!再线讨论!! c#访问FOXPOR数据库问题 WORD求源代码加分之四 怎么样获得一个 EDIT 的 句柄 ?? 请问嵌入网页中的Activex如何调整自身的大小?请各位高手帮忙!谢谢! Oracle和SQLSERVER中5用户10用户到底是什么意思? 我身边的一个PLMM说,她想找一个成熟、幽默、聪明的程序员。 一个局域网内访问odbc数据源的问题 对女孩子不能太热情了! 一个easy 的question 请精通C#与VB.net的大虾帮忙翻译一下 在异地拷贝一个文件(200M以上)到本地,如何做 《C++程序语言》(特别版)怎么样 getContentPane()是什么意思? 高手请进!嵌入网页中的Activex如何获取加载它的浏览器对象?谢谢! i am 24 year old ,but i have nothing 请问哪里有exchange2000 server??? XP,IE 6 SP1,安装JRE 1.4无数次,<APPLET>标签下的东西仍不能看,<OBJECT>可以,为什么??!!求救!! Socket发送接收的问题! c++ builder6的盘 mapx 问题? partition magic 8.0 一个既包含静态图象又包含视频播放的视频,怎样把它抓屏下来??? SOS!!!一个有关全文检索,以及文档的数据库存储的问题,急急!各位大侠出招啊,在线等候 请问如何在程序中将CEdit控件设为只读或取消只读, Java认证问题 请问你们认为哪种操作系统更好用和稳定? 关于mfc dll wizard 做出来的dll 的内存泄漏问题!! vc++与C++Builder有何本质的区别? 能否做个象Media Play的ACTIVEX查件,既有动画窗口,又有按钮??? 高手,关于数据库转换的问题 给分:谁有关于“从网卡取得数据”方面的论文 大家好,有一个关于拔号、专线系统的IP地址问题 SAX的问题 表单传递后,如何判断用户是否填入了内容的? 请教 请教各位大侠 各位好,小弟初学Oracle,请各位指点哪有相关电子书下载,多谢! 辞职,不知是对是错?(第一次散分,请版主高台贵手) 关于vb在com编程的几个问题! 例1:根据下列反应的焓变,计算C(石墨)与H2(g)反应生成1 molC2H2(g)的焓变. 苍耳靠什么传播种子长一点 染色质的四级结构为什么是染色单体而不是染色体? 计算C与H反应生成1MOLC2H2的焓变例1:根据下列反应的焓变,计算C(石墨)与H2(g)反应生成1 molC2H2(g)的焓变.C(石墨)+ O2(g)=CO2(g) △H1=-393.5kJ·mol-1 ①2 H2(g)+ O2(g)=2 H2O(l) △H2=-571.6kJ·mol-1 ②2 C2H2(g)+5O2(g)=4CO2( E=MC平方这个结论怎么来的大神们帮帮忙能量=质量X光速的平方 是怎么得来的 具体点的 如果是公式更好 染色体,染色质,姐妹染色体,姐妹染色单体的图各是怎样的?染色体,染色质,姐妹染色体,姐妹染色单体的图,要清晰的,最好是比例相同的,一目了然的,我脑子不好使.不然早会了!如果把染色体看作 根据下列反应的焓变,计算C(石墨)与H₂(g)反应生成1 molC₂H₂(g)的焓变.①C(石墨)+ O₂(g)=CO2(g) △H₁=-393.5kJ·mol-1 ②2H₂(g)+ O₂(g)=2 H₂O(l) △H₂=-571.6 下水管可能被小木块堵住了,有什么不切开管道的方法疏通吗堵在S弯处,而且已经看不到 染色体,染色质,染色单体有什么区别啊那染色单体与姐妹染色体有什么区别啊 苯环侧链氧化,侧链可能去了哪?如题 例如C6H5-CH2CH2CH2CH2CH2CH3 那一个C变-COOH 剩下的 CH2CH2CH2CH2CH3去了哪? 请问:苍耳靠什么传播种子?豌豆靠什么传播种子?还有什么靠什么传播种子? 请问;铜氨溶液分别和乙醇钠,葡萄糖,溴水发生反应吗 如果能 那反应方程式是什么 侧链受苯环的影响而易被氧化是什么意思? 太阳对地球引力做负功是什么? 把固体二氧化锰,和一种白色的粉末B混合产生氧气 二氧化锰和与盐酸反应的产物是什么? 在一定温度和压强下,50mlA2气体与75mlB2气体化合生成50ml气体化合物,则该化合物化学式为物质的量那块怎么求的 如右图,烧瓶内充满NH3,橡皮塞上没有胶头滴管,如何引发喷泉? 除杂题,co2(co)——通入氧气点燃,为什么不对? 物态除了气态液态和固态,还有什么物态? 税收三性中是强制性决定无偿性,还是无偿性决定强制性?具体表述如下 税收的强制性决定税收的无偿性,而税收三性中是强制性决定无偿性,还是无偿性决定强制性?具体表述如下税收的强制性 CO和CO2的混合气体18g,通入足量的氧气,点燃反应后测得CO2的总体积11.2L,求原混合气体中CO的质量 关于地震中救命三角的问题现在网上一直都在说什么地震中救命三角的方法,不知道是真是假,希望有人能站出来说说?因为这篇文章后面写了一个自治磁铁测地震的方法,这个方法很假很假有点 飞亚达表芯动男表瑞士自动机械机芯手表 GA8466BBB用的甚么机芯 CuSO4与CuSO4晶体有区别吗 为什么人类会受地球引力控制? 飞亚达石英表防水30米是指什么意思 硫酸铜为什么变成晶体?我需要知道硫酸铜怎么变成晶体的!实验过程我已经知道了,我想知道产生了什么化学或者物理反映!急 胶体中加电解质、加热、搅拌,为什么会聚沉?要原因? E=mc^2 能量我不明白把物体质量带进公式得到一个超级大的能量有什么作用?这些能量能做什么? H4[Fe(CN)6]是叫六氯合铁(Ⅱ)酸,还是六氯合亚铁(Ⅱ)酸 硫酸铜和硫酸铜晶体有什么区别吗? 胶体聚沉中加电解质是化学反应胶体粒子会吸附离子是化学反应吗? 二氧化锰与盐酸反应二氧化锰和盐酸制氯气,盐酸的最小浓度是多少?本人计算的答案是4.5mol如果答案选中,另外加给你! 为什么质粒上要有标记基因目的是? 栾树有几种呢?种植栾树将来的发展趋势如何? 一元强酸与一元强碱刚好完全中和时,一定相等的是? A.酸和碱的质量 B.酸和碱的质量分数A.酸和碱的质量 B.酸和碱的质量分数 C.酸和碱的物质的量的浓度 D.氢离子和氢氧根离子的物质的量 质粒中怎么对标记基因进行筛选质粒如果自身进行环化连接同样具有这个标记基因,这该怎么把它区分出来 哪里有栾树哪里有栾树苗 二氧化锰和盐酸怎样反应 质力 玻璃为什么在玻璃烧制中 不能立刻成型 要放一个星期释放质力 这是为什么这个质力要是什么呢 【松子】松子的营养价值高在哪里 DNA具体在哪一时期开始复制? MC我的世界细菌mod怎么使用?什么细菌增生方块之类的,怎么用? 氯化铁溶液中是否存在少量氢氧化铁和氢氧化亚铁沉淀 DNA复制完成后分开的时期为 浓硫酸溅到手上,可以用干抹布擦吗 地震的生命三角区有哪些位置? 抗生素抗性标记基因 知道什么是抗生素抗性标记基因? 浓硫酸占到手上能否立即涂上氢氧化钙溶液?如果立即用抹布擦抹布不就变成C了? 与鬼针草、苍耳传播方式相同一个果实有四个种子的植物. 在基因工程中.标记基因和抗性基因描述的是同一个东西吗? 水厂河中700取水管被沙石堵塞一半怎么疏通 政治理论常识有哪些具体的内容? 计算c(石墨)与H2(g)反应生成1molC2H2(g)的焓变C(石墨)+ O2(g)=CO2(g) △H1=-393.5kJ·mol-1 ①2 H2(g)+ O2(g)=2 H2O(l) △H2=-571.6kJ·mol-1 ②2 C2H2(g)+5O2(g)=4CO2(g) + 2 H2O(l) △H3=-2599.2kJ·mol-1 ③答:盖斯定律.就是把题目 我怀念朋友 扩写句子 实验室中硫酸亚铁或氯化亚铁溶液长时间放置将会有什么变化 根据下列反应的焓变,计算C(石墨)与H2(g)反应生成1mol例1:根据下列反应的焓变,计算C(石墨)与H2(g)反应生成1 molC2H2(g)的焓变.C(石墨)+ O2(g)=CO2(g) △H1=-393.5kJ·mol-1 ①2 H2(g)+ O2(g)=2 H2O(l) △H2=-571.6kJ·mol- 我怀念朋友.怎么扩句 高一寒假课程导学73页:氨气的喷泉实验探究操作中:为什么先挤压胶头滴管的胶头,后打开止水夹更好?氨气的喷泉实验成功的关键有(1)装置的气密性良好,为什么?如果不好,有啥影响?如果 美国:伊拉克“平衡木”不好走克里承认美国一些监听行为很过分联合国官员:目前还在讨论叙利亚化武销美国防部否认美日制定钓鱼岛防卫计划联合国官员:目前还在讨论叙利亚化武销洛杉矶机场枪击案嫌犯身份确定 被指曾水泥槽罐车侧翻压住红色宝马 永康一对非洲沙漠车抛锚90人干渴而亡画面曝光田径名将史冬鹏河北保定大婚 体育局领田径名将史冬鹏今日大婚 新娘是其师妹43名中国人涉非法采金被加纳抓扣 2PMI升至18月最高 中国经济第三季同济大学与联合国机构合推绿色经济教材全国最大网络传销案终审:维持原判主犯德国政府决定婴儿出生证可填写“未确定洛杉矶机场枪击案嫌犯身份确定 被指曾洛杉矶机场枪击案疑犯写有反政府字条 德国老人中奖1300万欧元 自称通过王力宏王菲樱井翔 揭大牌明星的惊人背土耳其4名女议员戴头巾出席会议 打破日媒:中国调查船驶入钓鱼岛附近“专属北京卫计委主任:建议将号贩子入刑书店有约“偏远山区非婚生子是留守儿童出现主要刘慈欣:只是称号 不影响写作燕山快笔“不能因为尚未成年就不追责”上交所展开“刨根问底”式监管八达岭动物园一经理被大象踩死救命手术台何以屡现“持刀加价”俗世偏偏多奇人闲篇儿布鲁诺没时间关注日本队表现 坦言当教铿锵玫瑰再现 奥运前景光明熊孩子“中国创翼”赛北京初赛启动彩票开奖公告“医强险”能让医闹消失吗个人税收优惠健康险正式落地香港特首支持港人内地创业今年军费增幅在7% 8%之间 5年《西游奇遇记》今晚收官
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘