当前位置: 首页 > news >正文

可以做空股票的网站做行政关注什么类型的网站

可以做空股票的网站,做行政关注什么类型的网站,为什么要建设营销型网站,建一个动物网站怎么做美团是中国最大的O2O交易平台#xff0c;目前已拥有近6亿用户#xff0c;合作各类商户达432万#xff0c;订单峰值突破1150万单。美团App是平台主要的入口之一#xff0c;O2O交易场景的复杂性决定了App稳定性要达到近乎苛刻的要求。用户到店消费买优惠券时死活下不了单目前已拥有近6亿用户合作各类商户达432万订单峰值突破1150万单。美团App是平台主要的入口之一O2O交易场景的复杂性决定了App稳定性要达到近乎苛刻的要求。用户到店消费买优惠券时死活下不了单定外卖一个明显可用的红包怎么点也选不中上了一个新活动用户一点就Crash……过去发生过的这些画面太美不敢想象。客户端相对Web版最大的短板就是有发版的概念对线上事故很难有即时生效的解决方式每次发版都如临深渊如履薄冰毕竟就算再完善的开发测试流程也无法保证不会将Bug带到线上。 从去年开始Android平台出现了一些优秀的热更新方案主要可以分为两类一类是基于multidex的热更新框架包括Nuwa、Tinker等另一类就是native hook方案如阿里开源的Andfix和Dexposed。这样客户端也有了实时修复线上问题的可能。但经过调研之后我们发现上述方案或多或少都有一些问题基于native hook的方案需要针对dalvik虚拟机和art虚拟机做适配需要考虑指令集的兼容问题需要native代码支持兼容性上会有一定的影响基于Multidex的方案需要反射更改DexElements改变Dex的加载顺序这使得patch需要在下次启动时才能生效实时性就受到了影响同时这种方案在android N [speed-profile]编译模式下可能会有问题可以参考Android N混合编译与对热补丁影响解析。考虑到美团Android用户机型分布的碎片化很难有一个方案能覆盖所有机型。 去年底的Android Dev Summit上Google高调发布了Android Studio 2.0其中最重要的新特性Instant Run实现了对代码修改的实时生效热插拔。我们在了解Instant Run原理之后实现了一个兼容性更强的热更新方案这就是产品化的hotpatch框架Robust。 Robust插件对每个产品代码的每个函数都在编译打包阶段自动的插入了一段代码插入过程对业务开发是完全透明。如State.java的getIndex函数 public long getIndex() {return 100;}被处理成如下的实现 public static ChangeQuickRedirect changeQuickRedirect;public long getIndex() {if(changeQuickRedirect ! null) {//PatchProxy中封装了获取当前className和methodName的逻辑并在其内部最终调用了changeQuickRedirect的对应函数if(PatchProxy.isSupport(new Object[0], this, changeQuickRedirect, false)) {return ((Long)PatchProxy.accessDispatch(new Object[0], this, changeQuickRedirect, false)).longValue();}}return 100L;}可以看到Robust为每个class增加了个类型为ChangeQuickRedirect的静态成员而在每个方法前都插入了使用changeQuickRedirect相关的逻辑当 changeQuickRedirect不为null时可能会执行到accessDispatch从而替换掉之前老的逻辑达到fix的目的。 如果需将getIndex函数的返回值改为return 106那么对应生成的patch主要包含两个classPatchesInfoImpl.java和StatePatch.java。 PatchesInfoImpl.java: public class PatchesInfoImpl implements PatchesInfo {public ListPatchedClassInfo getPatchedClassesInfo() {ListPatchedClassInfo patchedClassesInfos new ArrayListPatchedClassInfo();PatchedClassInfo patchedClass new PatchedClassInfo(com.meituan.sample.d, StatePatch.class.getCanonicalName());patchedClassesInfos.add(patchedClass);return patchedClassesInfos;} }StatePatch.java public class StatePatch implements ChangeQuickRedirect {Overridepublic Object accessDispatch(String methodSignature, Object[] paramArrayOfObject) {String[] signature methodSignature.split(:);if (TextUtils.equals(signature[1], a)) {//long getIndex() - areturn 106;}return null;}Overridepublic boolean isSupport(String methodSignature, Object[] paramArrayOfObject) {String[] signature methodSignature.split(:);if (TextUtils.equals(signature[1], a)) {//long getIndex() - areturn true;}return false;} }客户端拿到含有PatchesInfoImpl.java和StatePatch.java的patch.dex后用DexClassLoader加载patch.dex反射拿到PatchesInfoImpl.java这个class。拿到后创建这个class的一个对象。然后通过这个对象的getPatchedClassesInfo函数知道需要patch的class为com.meituan.sample.dcom.meituan.sample.State混淆后的名字再反射得到当前运行环境中的com.meituan.sample.d class将其中的changeQuickRedirect字段赋值为用patch.dex中的StatePatch.java这个class new出来的对象。这就是打patch的主要过程。通过原理分析其实Robust只是在正常的使用DexClassLoader所以可以说这套框架是没有兼容性问题的。 大体流程如下 OK到这里Robust原理就介绍完了。很简单是不是而且sample这个例子中也验证成功了。难道一切这么顺利其实现实并不是这样我们将这套实现用到美团的主App时问题出现了 Conversion to Dalvik format failed:Unable to execute dex: method ID not in [0, 0xffff]: 65536居然不能打出包来了从原理上分析除了引入的patch过程aar外我们这套实现是不会增加别的方法的而且引入的那个aar的方法才100个左右怎么会造成美团的mainDex超过65536呢进一步分析我们一共处理7万多个函数导致最后方法数总共增加7661个。这是为什么呢 看下patch前后的dex对比 针对com.meituan.android.order.adapter.OrderCenterListAdapter.java分析一下发现进行hotpatch之后增加了如下6个方法 public boolean isEditMode() {return isEditMode;} private int incrementDelCount() {return delCount.incrementAndGet();} private boolean isNeedDisplayRemainingTime(OrderData orderData) {return null ! orderData.remindtime getRemainingTimeMillis(orderData.remindtime) 0;} private boolean isNeedDisplayUnclickableButton(OrderData orderData) {return null ! orderData.remindtime getRemainingTimeMillis(orderData.remindtime) 0;} private boolean isNeedDisplayExpiring(boolean expiring) {return expiring isNeedDisplayExpiring;} private View getViewByTemplate(int template, View convertView, ViewGroup parent) {View view null;switch (template) {case TEMPLATE_DEFALUT:default:view mInflater.inflate(R.layout.order_center_list_item, null);}return view;}但是这些多出来的函数其实就在原来的产品代码中为什么没有Robust的情况下不见了而使用了插件后又出现在最终的class中了呢只有一个可能就是ProGuard的内联受到了影响。使用了Robust插件后原来能被ProGuard内联的函数不能被内联了。看了下ProGuard的Optimizer.java的相关片段 if (methodInliningUnique) {// Inline methods that are only invoked once.programClassPool.classesAccept(new AllMethodVisitor(new AllAttributeVisitor(new MethodInliner(configuration.microEdition,configuration.allowAccessModification,true,methodInliningUniqueCounter)))); } if (methodInliningShort) {// Inline short methods.programClassPool.classesAccept(new AllMethodVisitor(new AllAttributeVisitor(new MethodInliner(configuration.microEdition,configuration.allowAccessModification,false,methodInliningShortCounter)))); }通过注释可以看出如果只被调用一次或者足够小的函数都可能被内联。深入分析代码我们发现确实如此只被调用了一次的私有函数、只有一行函数体的函数比如get、set函数等都极可能内联。前面com.meituan.android.order.adapter.OrderCenterListAdapter.java多出的那6个函数也证明了这一点。知道原因了就能有解决问题的思路。 其实仔细思考下那些可能被内联的只有一行函数体的函数真的有被插件处理的必要吗别说一行代码的函数出问题的可能性小就算出问题了也可以通过patch内联它的那个函数来解决问题或者patch这一行代码调用的那个函数。只调用了一次的函数其实是一样的。所以通过分析这样的函数其实是可以不被插件处理的。那么有了这个认识我们对插件做了处理函数的判断跳过被ProGuard内联可能性比较大的函数。重新在团购试了一次这次apk顺利的打包出来了。通过对打出来apk中的dex做分析发现优化后的插件还是影响了内联效果不过只导致方法数增加了不到1000个所以算是临时简单的解决了这个问题。 原理上Robust是为每个函数都插入了一段逻辑为每个class插入了ChangeQuickRedirect的字段所以最终肯定会增加apk的体积。以美团主App为例平均一个函数会比原来增加17.47个字节整个App中我们一共处理了6万多个函数导致包大小由原来的19.71M增加到了20.73M。有些class没有必要添加ChangeQuickRedirect字段以后可以通过将这些class过滤掉的方式来做优化。 Robust在每个方法前都加上了额外的逻辑那对性能上有什么影响呢 从图中可以看到对一个只有内存运算的函数处理前后分别执行10万次的时间增加了128ms。这是在华为4A上的测试结果。 对启动速度上的影响 在同一个机器上的结果处理前后的启动时间相差了5ms。 再来看看补丁本身。要制作出补丁我们可能会面临如下两个问题 1. 如何解决混淆问题 2. 被补的函数中使用了super相关的调用怎么办 其实混淆的问题比较好处理。先针对混淆前的代码生成patch.class然后利用生成release包时对应的mapping文件中的class的映射关系对patch.class做字符串上的处理让它使用线上运行环境中混淆的class。 被补的函数中使用了super相关的调用怎么办比如某个Activity的onCreate方法中需要调用super.onCreate而现在这个bad.Class的badMethod就是这个Activity的onCreate方法那么在patched.class的patchedMethod中如何通过这个Activity的对象调用它父类的onCreate方法呢通过分析Instant Run对这个问题的处理发现它是在每个class中都添加了一个代理函数专门来处理super的问题的。为每个class都增加一个函数无疑会增加总的方法数这样做肯定会遇到65536这个问题。所以直接使用Instant Run的做法显然是不可取的。 在Java中super是个关键字也无法通过别的对象来访问到。看来想直接在patched.java代码中通过Activity的对象调用到它父类的onCreate方法有点不太可能了。不过通过对class文件做分析发现普通的函数调用是使用JVM指令集的invokevirtual指令而super.onCreate的调用使用的是invokesuper指令。那是不是将class文件中这个调用的指令改为invokesuper就好了看如下的例子 产品代码SuperClass.java public class SuperClass {String uuid;public void setUuid(String id) {uuid id;}public void thisIsSuper() {Log.d(SuperClass, thisIsSuper uuid);} }产品代码TestSuperClass.java public class TestSuperClass extends SuperClass{String subUuid;public void setSubUuid(String id) {subUuid id;}Overridepublic void thisIsSuper() {Log.d(TestSuperClass, thisIsSuper no call);} }TestSuperPatch.java是DexClassLoader将要加载的代码 public class TestSuperPatch {public static void testSuperCall() {TestSuperClass testSuperClass new TestSuperClass();String t UUID.randomUUID().toString();Log.d(TestSuperPatch, UUID t);testSuperClass.setUuid(t);testSuperClass.thisIsSuper();} }对TestSuperPatch.class的testSuperClass.thisIsSuper()调用做invokesuper的替换并且将invokesuper的调用作用在testSuperClass这个对象上然后加载运行 Caused by: java.lang.NoSuchMethodError: No super method thisIsSuper()V in class Lcom/meituan/sample/TestSuperClass; or its super classes (declaration of com.meituan.sample.TestSuperClass appears in /data/app/com.meituan.robust.sample-3/base.apk)报错信息说在TestSuperClass和TestSuperClass的父类中没有找到thisIsSuper()V函数但是实际上TestSuperClass和父类中是存在thisIsSuper()V函数的而且通过apk反编译看也确实存在的那怎么就找不到呢分析invokesuper指令的实现发现系统会在执行指令所在的class的父类中去找需要调用的方法所以要将TestSuperPatch跟TestSuperClass一样作为SuperClass的子类。修改如下 public class TestSuperPatch extends SuperClass {... }然后再做一次尝试 08-11 09:12:03.012 1787-1787/? D/TestSuperPatch: UUID c5216480-5c3a-4990-896d-58c3696170c5 08-11 09:12:03.012 1787-1787/? D/SuperClass: thisIsSuper c5216480-5c3a-4990-896d-58c3696170c5看一下testSuperCall的实现将UUID.randomUUID().toString()的结果通过setUuid赋值给了testSuperClass这个对象的父类的uuid字段。从日志可以看出对testSuperClass.thisIsSuper处理后确实是调用到了testSuperClass这个对象的super的thisIsSuper函数。OKsuper的问题看来解决了而且这种方式不会增加方法数。 Robust 靠谱吗 尝试修个线上的问题我们是在07.14下午17:00多的时候上线的补丁我们可以看到接下来的几天一直到07.17号将补丁下线这个线上问题得到了明显的修复补丁下线后看到07.18号这个问题又明显上升了。直到07.18号下班前又重新上线补丁。 补丁的兼容性和成功率如何通过以上的理论分析可以看到这套实现基本没有兼容性问题实际上线的数据如下 先简单解释下这几个指标 补丁列表拉取成功率拉取补丁列表成功的用户/尝试拉取补丁列表的用户 补丁下载成功率下载补丁成功的用户/补丁列表拉取成功的用户 patch应用成功率patch成功的用户/补丁下载成功的用户 通过这个表能够看出我们的patch信息拉取的成功最低平均97%多这是因为实际的网络原因而下载成功后的patch成功率是一直在99.8%以上。而且我们做的是无差别下发服务端没有做任何针对机型版本的过滤线上的结果再次证明了Robust的高兼容性。 目前业界已有的Android App热更新方案包括Multidesk和native hook两类都存在一些兼容性问题。为此我们借鉴Instant Run原理实现了一个兼容性更强的热更新方案Robust。Robust除了高兼容性之外还有实时生效的优势。so和资源的替换目前暂时未做实现但是从框架上来说未来是完全有能力支持的。当然这套方案虽然对开发者是透明的但毕竟在编译阶段有插件侵入了产品代码对运行效率、方法数、包体积还是产生了一些副作用。这也是我们下一步努力的方向。 Instant Run, Android Tools Project Site, http://tools.android.com/tech-docs/instant-run.Oracle, The Java Virtual Machine Instruction Set, https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html.Oracle, ClassLoader, https://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html).ltshddx, https://github.com/ltshddx/jaop).w4lle, Android热补丁之AndFix原理解析.shwenzhang, Android N混合编译与对热补丁影响解析.
http://www.zqtcl.cn/news/130444/

相关文章:

  • 网站建设网站设计多少钱网站系统开发方式
  • 站长收录wordpress配置好后别人无法访问
  • 我国档案网站建设吉林网站建设制作
  • 手机网站底部导航网站视频链接怎么做
  • 企业门户网站属于什么层seo关键词排行优化教程
  • wordpress 演示站广东省南粤交通投资建设有限公司网站
  • 典型的企业网站张家港保税区建设规划局网站
  • 网站设计公司那个好网页设计登录界面模板
  • 做网站的厂家聚美优品网站设计
  • 哈尔滨网站建设效果好网站改版 影响google 404跳首页
  • 廊坊网站推广的公司如何做1个手机网站
  • 网站index.php被修改南京cms建站系统
  • 淘宝网站模板是什么做的北海建设厅网站
  • 我想建个网站想做电商应该怎么入门
  • 广州番禺网站制作推广网站建设徐州百度网络网站
  • 有没有个人做网站的新网站做seo 的效果
  • 做网站和app哪个简单旅游资讯网站建设方案
  • 网站建设考级百度怎样可以搜到自己的网站
  • 自助建站免费自助建站网站广州企业网站
  • 常德论坛尚一网唐山seo网络推广
  • 网站建设预付流程网站设计风格的关键词
  • 常德网站制作怎么做自己的网页
  • 做的网站为什么图片看不了wordpress循环该分类子分类
  • 源码出售网站怎么做一个产品的网络营销方案
  • 安丘营销型网站建设国外教育网站模板
  • 做网站案例百度小说排行榜前十
  • 东昌网站建设公司上传到网站去的文档乱码
  • 如何制作自己的网站链接教程网络营销seo招聘
  • 网站制作资料收集wordpress资源网模板
  • 随州网站设计开发服务做网站制作步骤