SlideShare une entreprise Scribd logo
1  sur  47
Télécharger pour lire hors ligne
Android
                         DevCamp
                         Produced by CSDN
                 Website: http://devcamp.csdn.net/
                 Weibo: http://weibo.com/cmdnclub/




Thursday, August 2, 12
创建更加灵活的App



Thursday, August 2, 12
Why
                     •   无法消灭旧版本,版本维护周期过长

                     •   基于版本的迭代速度缓慢

                     •   上线后无法调整

                     •   Bug造成的影响无法即使消除

                     •   。。。




Thursday, August 2, 12
What Matters

                     • 需求驱动

                     • 成本 与 收益


Thursday, August 2, 12
案例
                     •   2010年,当时用户体验最好,用户数最多的地图类应
                         用是Google Maps

                     •   但是Google Maps面临最大的问题是速度慢,经常被墙

                     •   国内的地图应用成为主流只是时间问题



                     •   如何在外部环境发生变化后及时调整?




Thursday, August 2, 12
需求
                     •   避免弹出Pick Activity对话框,根据用户手机有没有安
                         装该地图应用决定默认打开哪款地图。优先级如下:
                                  Priority List:
                                     1. Google Maps
                                     2. Google Maps (Brut)
                                     3. 百度地图
                                     4. 图吧地图
                                     5. Mini Map
                                     ...


                     •   查看地图是⼀一个非常关键的功能点 ,优先级需要随时
                         调整,并在已发布的客户端也同时生效



Thursday, August 2, 12
问题
                     •   每款地图应用都定义了自己的Intent调用方式

                     •   对于未知的地图应用,如何创建对应的Intent?

                     •   是否需要针对地图应用的版本号来采取不同的优先级
                         策略?




Thursday, August 2, 12
最初方案
                     •   把策略和创建Intent交给服务器端解决

                          •   bla bla ...




Thursday, August 2, 12
把精力放在解决80%的用户需求上




Thursday, August 2, 12
最终方案
                     •   放弃支持未知地图应用

                     •   放弃支持版本号判断




                     •   把Priority List加入远程配置中

                     •   客户端负责顺序判断,并创建地图应用对应的Intent



Thursday, August 2, 12
配置

                                 Remote
                         http://api.myserver.com/config?
                         client=myapp&version=1.0&...

                                cached on local disk



                            {
                                ver:”20120701”,
                                mapList: [
                                 “Baidu”,
                                 “Google”,
                                 “Google(Brut)”,
                                 “Mapbar”,
                                 ...
                                 ]
                            }


Thursday, August 2, 12
配置

                                 Remote                          User
                         http://api.myserver.com/config?
                                                              SharedPreference
                         client=myapp&version=1.0&...

                                cached on local disk      stored on local disk



                            {
                                ver:”20120701”,
                                mapList: [
                                                          {
                                 “Baidu”,
                                                              mapList: [
                                 “Google”,
                                                               “Baidu”
                                 “Google(Brut)”,
                                                               ]
                                 “Mapbar”,
                                                          }
                                 ...
                                 ]
                            }


Thursday, August 2, 12
配置

                    Default                   Remote                          User
                     MyApp.apk        http://api.myserver.com/config?
                                                                           SharedPreference
                     |-res            client=myapp&version=1.0&...
                       |-raw
                                             cached on local disk      stored on local disk
                         |-default


               {                         {
                   ver: “20120101”,          ver:”20120701”,
                   mapList: [                mapList: [
                                                                       {
                    “Google”,                 “Baidu”,
                                                                           mapList: [
                    “Google(Brut)”,           “Google”,
                                                                            “Baidu”
                    “Baidu”,                  “Google(Brut)”,
                                                                            ]
                    “Mapbar”,                 “Mapbar”,
                                                                       }
                    ...                       ...
                    ]                         ]
               }                         }


Thursday, August 2, 12
配置
                     •   简单实用,可以满足大部分的简单需求



                     •   新版本提示

                     •   特定功能的开启或关闭

                     •   产品运营相关

                     •   等等



Thursday, August 2, 12
HTML5
                         Hybrid Application




Thursday, August 2, 12
PhoneGap
                         详见 http://phonegap.com




Thursday, August 2, 12
Why Not?
                     •   PhoneGap要做到和Native Activity的整合较困难

                     •   2010年的手机性能运行PhoneGap的界面流畅度不好

                     •   好的Web前端设计师太难招了




                     •   那个时候还没有PhoneGap



Thursday, August 2, 12
Activity Stack
                         首页                dianping://home

                          活动推广(HTML)           http://dianping.com/a1.html

                              列表                   dianping://list?ids=12,32,44

                               商户详情                     dianping://info?id=12




Thursday, August 2, 12
URL Scheme
                     •   dianping://shopinfo?id=123456
                                   <activity
                                       android:name="com.dianping.find.ui.activity.ShopInfoActivity"
                                       android:configChanges="orientation|keyboardHidden"
                                       android:label="商户信息"
                                       android:screenOrientation="nosensor" >
                                       <intent-filter>
                                           <action android:name="android.intent.action.VIEW" />

                                           <category android:name="android.intent.category.BROWSABLE" />
                                           <category android:name="android.intent.category.DEFAULT" />

                                           <data
                                               android:host="shopinfo"
                                               android:scheme="dianping" />
                                       </intent-filter>
                                   </activity>




Thursday, August 2, 12
URL Scheme
                     •       HTML
                                      <a href="dianping://shopinfo?id=123456">查看商户详情</a>




                     •       Intent

                         	    	   	    Intent i = new Intent(Intent.ACTION_VIEW,
                         	    	   	    	 	 Uri.parse("dianping://shopinfo?id=123456"));
                         	    	   	    startActivity(i);




Thursday, August 2, 12
Simple is best
                     •   概念简单,就跟打开网站⼀一样,很容易跟别人解释清
                         楚。

                     •   实现简单,几行代码就能实现。

                     •   跨平台,iOS和Android都可以采用。

                     •   微信、支付宝等程序间的交互。




Thursday, August 2, 12
团购
                     •   需求变数多

                     •   主要业务由网站开发团队负责,移动只提供框架



                     •   用HTML开发,需要同时支持iOS和Android

                     •   HTML能够向Java代码获取信息,如用户账户等信息

                     •   能够指定在不同的Activity中打开不同的页面



Thursday, August 2, 12
数据传递
                     •   Android Javascript Bridge
                          public void addJavascriptInterface(Object object, String name)




                     •   WebView URL Override (Android & iOS)
                         public boolean shouldOverrideUrlLoading(WebView view, String url)




                                      http://myapp.com/checkout?user=!&token=!


                              http://myapp.com/checkout?user=123&token=e3a12f54c123




Thursday, August 2, 12
Activity Stack管理
                     •   URL Override

                     •   支持压入堆栈和抛出堆栈



                     •   。。。




Thursday, August 2, 12
出现问题
                     •   不同Android版本的WebView有不⼀一致的行为

                     •   列表页面高度逐渐增大,UI相应速度缓慢直至完全不
                         响应

                     •   jQuery或MooTools当时没有为移动设备做优化,类库
                         太重,耗费资源严重。

                     •   在不同的Activity和WebView中打开网页导致严重依赖
                         Cookie,管理成本高。




Thursday, August 2, 12
最终
                     •   用户普遍不认可HTML的开发方式,各种抱怨

                     •   浏览率低,订单转化率低,支付成功率低,各种低

                     •   损失的都是钱那




Thursday, August 2, 12
惨痛的教训
                     •   用户体验通常是Native比HTML好

                     •   Web开发和移动开发还是有显著区别的,沟通成本很
                         高

                     •   如果HTML只是临时方案,不要做过多的框架设计,
                         但是⼀一定要考虑今后迁移到Native的可行性

                     •   考虑成本和收益




Thursday, August 2, 12
脚本语言
                         Lua & Python




Thursday, August 2, 12
脚本语言的问题
                     •   dalvik下无法创建新的类

                     •   Java是静态类型,脚本语言调用需要指定类型,代码非常冗余

                     •   使用C/C++实现的Lua和Python解释器面临的问题

                          •   无法直接在Lua/Python中引用Java对象(内存地址变化)

                          •   需要经过JNI来中转所有调用,中间层实现成本较高


                               Java       JNI      Lua/Python

                     •   使用Java实现的Lua和Python解释器效率较低,且可靠性未知



Thursday, August 2, 12
动态加载
                         Dalvik Executable File
                                   &
                               Resources




Thursday, August 2, 12
DexClassLoader

                         DexClassLoader dcl = new DexClassLoader(
                         	 	 "/sdcard/dex.apk", "/sdcard/dexout/",
                         	 	 null, super.getClassLoader());
                         Class c = dcl.loadClass("com.package.MyClass");
                         Object myObj = c.newInstance();




Thursday, August 2, 12
定位项目需求
                     •   初步证明android.location.LocationManager存在优化空
                         间

                     •   进⼀一步的优化需要通过线上数据及反馈进行迭代

                     •   迭代周期为1~2周⼀一次

                     •   每次迭代都需要在线上环境做A/B Test以验证有效




Thursday, August 2, 12
定位服务


                           dianping.apk                       dynamic.apk

                         interface LocationService


                                                             class LocationServiceImpl
                 class DexLocationServiceWrapper            implements LocationService
                     implements LocationService
            {
                 private LocationService mService;
            }




Thursday, August 2, 12
上线后
                     •   完全摆脱了App上线周期和版本的限制

                     •   新老版本的App都运行着最新版本的定位服务

                     •   不同App运行着最新版本的定位服务,不需要再merge
                         了

                     •   团队可以独立运作



                     •   偶尔还可以帮忙解个线上Bug。。


Thursday, August 2, 12
下⼀一步
                     •   所有代码都动态加载



                     •   如何动态加载⼀一个Activity?




Thursday, August 2, 12
动态加载Activity


                         Application

                             mBase : ContextImpl

                                mPackageInfo : LoadedApk

                                       mClassLoader : PathClassLoader




Thursday, August 2, 12
DEMO
                         Activity Override




Thursday, August 2, 12
缺陷
                     •   用了很多Hacking,不能保证未来系统的兼容性

                     •   Activity必须要在AndroidManifest.xml中注册,所以无法
                         通过动态加载的方法新增Activity




                     •   Resources资源文件没有解决




Thursday, August 2, 12
重新思考
                     •   Activity继承自ContextWrapper,每个Activity都有能力
                         改变自己的上下文环境。

                     •   Android 3.0 引入了救星Fragment。Fragment就是小⼀一
                         号的Activity,但也能够满足需求了。

                     •   Activity作为Fragment运行的容器,提供ClassLoader和
                         Resources相关的环境。




Thursday, August 2, 12
代码                   资源

                                      Activity.getAssets()

         Activity.getClassLoader()   Activity.getResources()

                                      Activity.getTheme()




Thursday, August 2, 12
DEMO
                         Fragment Loader




Thursday, August 2, 12
Resources重复问题
                     •   Android的资源文件通过R.java来索引

                     •   手动分配不同的id,在不同层级的apk中通过res/values/
                         public.xml来分配

                     •   通过重载AssetManager中的隐藏函数来区分不同区段
                         的id,并返回对应apk包中的资源

                     •   (需要特殊的编译方式)




Thursday, August 2, 12
数据类型
                     •   采用Java类封装数据的方式过于繁重

                     •   建议采用松散数据类型在各个模块之间进行交互(类似
                         JSONObject)




Thursday, August 2, 12
其他问题
                     •   模块粒度问题

                     •   Intent如何表示

                     •   损失的Activity属性如何弥补




Thursday, August 2, 12
优点
                     •   采用插件的模式,功能模块独立开发,独立上线

                     •   开发彻底解耦

                     •   解决了编译时间过长的问题

                     •   主程序apk包大小可以减小




Thursday, August 2, 12
HTML + Dex
                           Javascript Bridge




Thursday, August 2, 12
Thanks



Thursday, August 2, 12

Contenu connexe

Plus de imShining @DevCamp

Plus de imShining @DevCamp (10)

发现和建立多设备之间的数据通信 | 豌豆荚实验室 孙桥
发现和建立多设备之间的数据通信 | 豌豆荚实验室 孙桥发现和建立多设备之间的数据通信 | 豌豆荚实验室 孙桥
发现和建立多设备之间的数据通信 | 豌豆荚实验室 孙桥
 
Android音频口数据通信开发 | 爱图腾 李鹏军
Android音频口数据通信开发 | 爱图腾 李鹏军Android音频口数据通信开发 | 爱图腾 李鹏军
Android音频口数据通信开发 | 爱图腾 李鹏军
 
凡客移动应用之Android + HTML5技术运用 | 凡客 汪健飞 徐金山
凡客移动应用之Android + HTML5技术运用 | 凡客 汪健飞 徐金山凡客移动应用之Android + HTML5技术运用 | 凡客 汪健飞 徐金山
凡客移动应用之Android + HTML5技术运用 | 凡客 汪健飞 徐金山
 
Android账户同步备份框架 | 盛大乐众ROM 郭振
Android账户同步备份框架 | 盛大乐众ROM 郭振 Android账户同步备份框架 | 盛大乐众ROM 郭振
Android账户同步备份框架 | 盛大乐众ROM 郭振
 
简单中的不简单,iPhone应用开发实践总结:《社区类iPhone应用开发的技术实践》| 麻麻帮 陈剑飞
简单中的不简单,iPhone应用开发实践总结:《社区类iPhone应用开发的技术实践》| 麻麻帮 陈剑飞简单中的不简单,iPhone应用开发实践总结:《社区类iPhone应用开发的技术实践》| 麻麻帮 陈剑飞
简单中的不简单,iPhone应用开发实践总结:《社区类iPhone应用开发的技术实践》| 麻麻帮 陈剑飞
 
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
 
在iOS平台上实现全功能视频处理 | 盛大微酷 赵志猛
在iOS平台上实现全功能视频处理 | 盛大微酷 赵志猛在iOS平台上实现全功能视频处理 | 盛大微酷 赵志猛
在iOS平台上实现全功能视频处理 | 盛大微酷 赵志猛
 
iOS平台应用详解:《Siri:I,robot! Siri语音识别系统详解》| 新浪 张俊林
iOS平台应用详解:《Siri:I,robot! Siri语音识别系统详解》| 新浪 张俊林iOS平台应用详解:《Siri:I,robot! Siri语音识别系统详解》| 新浪 张俊林
iOS平台应用详解:《Siri:I,robot! Siri语音识别系统详解》| 新浪 张俊林
 
《Passbook实战详解》| 爱图腾 廉洁 | iOS DevCamp
《Passbook实战详解》| 爱图腾 廉洁 | iOS DevCamp《Passbook实战详解》| 爱图腾 廉洁 | iOS DevCamp
《Passbook实战详解》| 爱图腾 廉洁 | iOS DevCamp
 
从知乎 iPhone 端重构说开去:Web 为主的复杂社交产品的 iOS 端开发策略及实践
从知乎 iPhone 端重构说开去:Web 为主的复杂社交产品的 iOS 端开发策略及实践从知乎 iPhone 端重构说开去:Web 为主的复杂社交产品的 iOS 端开发策略及实践
从知乎 iPhone 端重构说开去:Web 为主的复杂社交产品的 iOS 端开发策略及实践
 

如何创建更加灵活的App | 大众点评 屠毅敏

  • 1. Android DevCamp Produced by CSDN Website: http://devcamp.csdn.net/ Weibo: http://weibo.com/cmdnclub/ Thursday, August 2, 12
  • 3. Why • 无法消灭旧版本,版本维护周期过长 • 基于版本的迭代速度缓慢 • 上线后无法调整 • Bug造成的影响无法即使消除 • 。。。 Thursday, August 2, 12
  • 4. What Matters • 需求驱动 • 成本 与 收益 Thursday, August 2, 12
  • 5. 案例 • 2010年,当时用户体验最好,用户数最多的地图类应 用是Google Maps • 但是Google Maps面临最大的问题是速度慢,经常被墙 • 国内的地图应用成为主流只是时间问题 • 如何在外部环境发生变化后及时调整? Thursday, August 2, 12
  • 6. 需求 • 避免弹出Pick Activity对话框,根据用户手机有没有安 装该地图应用决定默认打开哪款地图。优先级如下: Priority List: 1. Google Maps 2. Google Maps (Brut) 3. 百度地图 4. 图吧地图 5. Mini Map ... • 查看地图是⼀一个非常关键的功能点 ,优先级需要随时 调整,并在已发布的客户端也同时生效 Thursday, August 2, 12
  • 7. 问题 • 每款地图应用都定义了自己的Intent调用方式 • 对于未知的地图应用,如何创建对应的Intent? • 是否需要针对地图应用的版本号来采取不同的优先级 策略? Thursday, August 2, 12
  • 8. 最初方案 • 把策略和创建Intent交给服务器端解决 • bla bla ... Thursday, August 2, 12
  • 10. 最终方案 • 放弃支持未知地图应用 • 放弃支持版本号判断 • 把Priority List加入远程配置中 • 客户端负责顺序判断,并创建地图应用对应的Intent Thursday, August 2, 12
  • 11. 配置 Remote http://api.myserver.com/config? client=myapp&version=1.0&... cached on local disk { ver:”20120701”, mapList: [ “Baidu”, “Google”, “Google(Brut)”, “Mapbar”, ... ] } Thursday, August 2, 12
  • 12. 配置 Remote User http://api.myserver.com/config? SharedPreference client=myapp&version=1.0&... cached on local disk stored on local disk { ver:”20120701”, mapList: [ { “Baidu”, mapList: [ “Google”, “Baidu” “Google(Brut)”, ] “Mapbar”, } ... ] } Thursday, August 2, 12
  • 13. 配置 Default Remote User MyApp.apk http://api.myserver.com/config? SharedPreference |-res client=myapp&version=1.0&... |-raw cached on local disk stored on local disk |-default { { ver: “20120101”, ver:”20120701”, mapList: [ mapList: [ { “Google”, “Baidu”, mapList: [ “Google(Brut)”, “Google”, “Baidu” “Baidu”, “Google(Brut)”, ] “Mapbar”, “Mapbar”, } ... ... ] ] } } Thursday, August 2, 12
  • 14. 配置 • 简单实用,可以满足大部分的简单需求 • 新版本提示 • 特定功能的开启或关闭 • 产品运营相关 • 等等 Thursday, August 2, 12
  • 15. HTML5 Hybrid Application Thursday, August 2, 12
  • 16. PhoneGap 详见 http://phonegap.com Thursday, August 2, 12
  • 17. Why Not? • PhoneGap要做到和Native Activity的整合较困难 • 2010年的手机性能运行PhoneGap的界面流畅度不好 • 好的Web前端设计师太难招了 • 那个时候还没有PhoneGap Thursday, August 2, 12
  • 18. Activity Stack 首页 dianping://home 活动推广(HTML) http://dianping.com/a1.html 列表 dianping://list?ids=12,32,44 商户详情 dianping://info?id=12 Thursday, August 2, 12
  • 19. URL Scheme • dianping://shopinfo?id=123456 <activity android:name="com.dianping.find.ui.activity.ShopInfoActivity" android:configChanges="orientation|keyboardHidden" android:label="商户信息" android:screenOrientation="nosensor" > <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.DEFAULT" /> <data android:host="shopinfo" android:scheme="dianping" /> </intent-filter> </activity> Thursday, August 2, 12
  • 20. URL Scheme • HTML <a href="dianping://shopinfo?id=123456">查看商户详情</a> • Intent Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("dianping://shopinfo?id=123456")); startActivity(i); Thursday, August 2, 12
  • 21. Simple is best • 概念简单,就跟打开网站⼀一样,很容易跟别人解释清 楚。 • 实现简单,几行代码就能实现。 • 跨平台,iOS和Android都可以采用。 • 微信、支付宝等程序间的交互。 Thursday, August 2, 12
  • 22. 团购 • 需求变数多 • 主要业务由网站开发团队负责,移动只提供框架 • 用HTML开发,需要同时支持iOS和Android • HTML能够向Java代码获取信息,如用户账户等信息 • 能够指定在不同的Activity中打开不同的页面 Thursday, August 2, 12
  • 23. 数据传递 • Android Javascript Bridge public void addJavascriptInterface(Object object, String name) • WebView URL Override (Android & iOS) public boolean shouldOverrideUrlLoading(WebView view, String url) http://myapp.com/checkout?user=!&token=! http://myapp.com/checkout?user=123&token=e3a12f54c123 Thursday, August 2, 12
  • 24. Activity Stack管理 • URL Override • 支持压入堆栈和抛出堆栈 • 。。。 Thursday, August 2, 12
  • 25. 出现问题 • 不同Android版本的WebView有不⼀一致的行为 • 列表页面高度逐渐增大,UI相应速度缓慢直至完全不 响应 • jQuery或MooTools当时没有为移动设备做优化,类库 太重,耗费资源严重。 • 在不同的Activity和WebView中打开网页导致严重依赖 Cookie,管理成本高。 Thursday, August 2, 12
  • 26. 最终 • 用户普遍不认可HTML的开发方式,各种抱怨 • 浏览率低,订单转化率低,支付成功率低,各种低 • 损失的都是钱那 Thursday, August 2, 12
  • 27. 惨痛的教训 • 用户体验通常是Native比HTML好 • Web开发和移动开发还是有显著区别的,沟通成本很 高 • 如果HTML只是临时方案,不要做过多的框架设计, 但是⼀一定要考虑今后迁移到Native的可行性 • 考虑成本和收益 Thursday, August 2, 12
  • 28. 脚本语言 Lua & Python Thursday, August 2, 12
  • 29. 脚本语言的问题 • dalvik下无法创建新的类 • Java是静态类型,脚本语言调用需要指定类型,代码非常冗余 • 使用C/C++实现的Lua和Python解释器面临的问题 • 无法直接在Lua/Python中引用Java对象(内存地址变化) • 需要经过JNI来中转所有调用,中间层实现成本较高 Java JNI Lua/Python • 使用Java实现的Lua和Python解释器效率较低,且可靠性未知 Thursday, August 2, 12
  • 30. 动态加载 Dalvik Executable File & Resources Thursday, August 2, 12
  • 31. DexClassLoader DexClassLoader dcl = new DexClassLoader( "/sdcard/dex.apk", "/sdcard/dexout/", null, super.getClassLoader()); Class c = dcl.loadClass("com.package.MyClass"); Object myObj = c.newInstance(); Thursday, August 2, 12
  • 32. 定位项目需求 • 初步证明android.location.LocationManager存在优化空 间 • 进⼀一步的优化需要通过线上数据及反馈进行迭代 • 迭代周期为1~2周⼀一次 • 每次迭代都需要在线上环境做A/B Test以验证有效 Thursday, August 2, 12
  • 33. 定位服务 dianping.apk dynamic.apk interface LocationService class LocationServiceImpl class DexLocationServiceWrapper implements LocationService implements LocationService { private LocationService mService; } Thursday, August 2, 12
  • 34. 上线后 • 完全摆脱了App上线周期和版本的限制 • 新老版本的App都运行着最新版本的定位服务 • 不同App运行着最新版本的定位服务,不需要再merge 了 • 团队可以独立运作 • 偶尔还可以帮忙解个线上Bug。。 Thursday, August 2, 12
  • 35. 下⼀一步 • 所有代码都动态加载 • 如何动态加载⼀一个Activity? Thursday, August 2, 12
  • 36. 动态加载Activity Application mBase : ContextImpl mPackageInfo : LoadedApk mClassLoader : PathClassLoader Thursday, August 2, 12
  • 37. DEMO Activity Override Thursday, August 2, 12
  • 38. 缺陷 • 用了很多Hacking,不能保证未来系统的兼容性 • Activity必须要在AndroidManifest.xml中注册,所以无法 通过动态加载的方法新增Activity • Resources资源文件没有解决 Thursday, August 2, 12
  • 39. 重新思考 • Activity继承自ContextWrapper,每个Activity都有能力 改变自己的上下文环境。 • Android 3.0 引入了救星Fragment。Fragment就是小⼀一 号的Activity,但也能够满足需求了。 • Activity作为Fragment运行的容器,提供ClassLoader和 Resources相关的环境。 Thursday, August 2, 12
  • 40. 代码 资源 Activity.getAssets() Activity.getClassLoader() Activity.getResources() Activity.getTheme() Thursday, August 2, 12
  • 41. DEMO Fragment Loader Thursday, August 2, 12
  • 42. Resources重复问题 • Android的资源文件通过R.java来索引 • 手动分配不同的id,在不同层级的apk中通过res/values/ public.xml来分配 • 通过重载AssetManager中的隐藏函数来区分不同区段 的id,并返回对应apk包中的资源 • (需要特殊的编译方式) Thursday, August 2, 12
  • 43. 数据类型 • 采用Java类封装数据的方式过于繁重 • 建议采用松散数据类型在各个模块之间进行交互(类似 JSONObject) Thursday, August 2, 12
  • 44. 其他问题 • 模块粒度问题 • Intent如何表示 • 损失的Activity属性如何弥补 Thursday, August 2, 12
  • 45. 优点 • 采用插件的模式,功能模块独立开发,独立上线 • 开发彻底解耦 • 解决了编译时间过长的问题 • 主程序apk包大小可以减小 Thursday, August 2, 12
  • 46. HTML + Dex Javascript Bridge Thursday, August 2, 12