现在的Android应用越来越庞大,开发者越来越能感受到方法数限制带来的影响。这里简单讲几个减少方法数的小建议。
1.什么是方法数?为什么它这么重要?
这要从dex的文件格式说起,在把源码编译、转化为dex文件格式时,dex文件中会有一个区域包含了所有源码中定义或引用的方法列表。这个区域中所有方法项的总数就是方法数。
很遗憾,Android在刚开始被设计的时候,这一区域的方法数量不能超过65536个,也就是2个字节表示的范围。当源码定义或引用的方法数量超过了这个限制的话,就会导致编译不成功,你说重要不重要呢?
2.如何查看这些方法?
可以使用修改过的dexdump。标准的dexdump可以解析方法列表,但无法打印出来,修改版的dexdump可以打印这些信息
如下是一个简单类LogicActivity中使用的方法
Class: Lcom/xxx/activity/LogicActivity; 18
Method: <init> ()V
Method: access$000 (Lcom/xxx/activity/LogicActivity;)Lcom/xxx/app/AppInterface;
Method: access$100 (Lcom/xxx/activity/LogicActivity;)Lcom/xxx/app/AppInterface;
Method: addFriend (Ljava/lang/String;ILjava/lang/String;)V
Method: addObserver (Lcom/xxx/app/BusinessObserver;)V
Method: finish ()V
Method: getIntent ()Landroid/content/Intent;
Method: getString (I)Ljava/lang/String;
Method: getTitleBarHeight ()I
Method: joinTroop ()V
Method: onActivityResult (IILandroid/content/Intent;)V
Method: onCreate (Landroid/os/Bundle;)V
Method: onDestroy ()V
Method: removeObserver (Lcom/xxx/app/BusinessObserver;)V
Method: setLastActivityName ()Ljava/lang/String;
Method: setResult (ILandroid/content/Intent;)V
Method: startActivity (Landroid/content/Intent;)V
Method: startActivityForResult (Landroid/content/Intent;I)V
可以看出,这里面的方法是包含代码中引用的方法的,如finish(),getIntent()这些方法。
3.减少方法数的办法
以下所介绍的方法都可以在修改后,用dexdump –j来观察、比较所修改的方法以及验证减少的效果。
方法1 避免在内部类中访问外部类的私有方法/变量
当在Java内部类(包括内部匿名类)中访问外部类的私有方法/变量时,编译器会生成额外的方法,这也会增加方法数,建议编码时尽量避免。
具体原因:
考虑如下的代码
publicclassFoo{ privateclassInner{ void stuff(){ Foo.this.doStuff(Foo.this.mValue); } } privateint mValue; publicvoid run(){ Innerin=newInner(); mValue =27; in.stuff(); } privatevoid doStuff(int value){ System.out.println("Value is "+ value); } }
虽然Java语言允许内部类直接访问外部类的方法,但是虚拟机却认为Foo和Foo$Inner是两个不同的类,为了支持Foo$Inner访问Foo的private成员,编译器会生成两个额外的方法,而生成的这些方法也算在方法总数里面
/*package*/staticintFoo.access$100(Foo foo){ return foo.mValue; } /*package*/staticvoidFoo.access$200(Foo foo,int value){ foo.doStuff(value); }
具体可以参考:http://developer.android.com/training/articles/perf-tips.html#PackageInner
解决办法:
很简单,把mValue和doStuff()的private修饰符去掉就好了,这样它的默认访问域为包级,编译器就不需要生成额外的代码。
方法2 避免调用派生类中的未被覆盖(override)的方法
考虑下面的代码
publicclass DemoActivity extends Activity { @Override protectedvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = getIntent(); if (intent.getAction().equals("add")) { finish(); } else { setContentView(R.id.background); } } }
实际上它会生成5个方法,除了定义的onCreate和构造函数之外,还有setContentView、getIntent()和finish()。因为按照java的语义,如果有覆盖父类的方法,则会直接调用覆盖的方法。
Class: Lcom/xxx/activity/DemoActivity; 5
Method: <init> ()V
Method: finish ()V
Method: getIntent ()Landroid/content/Intent;
Method: onCreate (Landroid/os/Bundle;)V
Method: setContentView (I)V
解决办法:
对于不需要被override的方法,显式的改成调用父类的方法,如下所示
publicclass DemoActivity extends Activity { @Override protectedvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = super.getIntent(); if (intent.getAction().equals("add")) { super.finish(); } else { super.setContentView(R.id.background); } } }
则实际在方法数列表中它只占2个方法
Class: Lcom/tencent/mobileqq/activity/DemoActivity; 2
Method: <init> ()V
Method: onCreate (Landroid/os/Bundle;)V
其实减少方法数还有很多办法,比如插件化之类的,后面有空再介绍。
另外,手机QQ空间长期招聘Android开发,有意者可以直接发送简历到邮箱 chroya.v@gmail.com,或者联系QQ 115818782,注明来意。
我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=5bex9jk0h28x
相关推荐
由于有多个 SDK 更新,建议有意识地组织开发环境,以便在不同的 SDK 安装之间轻松地切换。SDK 包括: android.jar Java 归档文件,其中包含构建应用程序所需的所有的 Android SDK 类。 documention.html 和 docs ...
前段时间学习了 Kotlin 的一些语法,然后就写了这个项目熟悉一下 Android的官方语言,总体下来,感觉比较爽,相比 Java 而言源代码行数有所减少、方法数也有所减少。 Kotlin 团队为 Android 开发提供了一套超
android安卓app开发教程之--总结了50条安卓开发经验.zip 34. 建议整个应用维护一个dbhelper实例,只要db没有关闭,全局就只有一个db实例,多线程并发写入db不会lock,严格交替进行写入:123123123。。。(123代表...
7.12.6 减少opengl es/jni方法的调用 7.12.7 绑定顶点的概念 7.12.8 写在结束之前 7.13 小结 第8章 2d游戏编程技巧 8.1 写在开始 8.2 向量 8.2.1 使用向量 8.2.2 一点三角学的知识 8.2.3 实现一个...
阅读建议:此资源以开发简化版android基础组件、多线程学习其原理和内核,不仅是代码编写实现也更注重内容上的需求分析和方案设计,所以在学习的过程要结合这些内容一起来实践,并调试对应的代码。
7.12.6 减少OpenGL ES/JNI方法的 调用 278 7.12.7 绑定顶点的概念 279 7.12.8 写在结束之前 282 7.13 小结 283 第8章 2D游戏编程技巧 285 8.1 写在开始 285 8.2 向量 286 8.2.1 使用向量 286 ...
日志较详细:因为android开发不支持热部署调试,运行报错时可根据日志来定位错误,这样可以减少运行Android的次数. * (二)不足之处: * 1.id暂时只支持int类型,不支持uuid,在sqlite中不建议用uuid. * 2....
Android开发资料汇总 刚开始接触某人新兴的技术,总是在网上漫无目的的搜索各种文章,而这些文章良莠不齐的,浪费时间来辨别这些东西是否对自己有用。后来在github上面看到了很多优秀的开源项目,浏览器收藏夹也不...
本文建议的是通过手写代码的方式来构造布局,等各个属性熟悉一些了再进行拖拽来减少工作量,加快开发速度。 先看看效果图吧: Normal(基础属性) 解析主要属性:其实也是使用的主要方法,按照这个伪代码去理解就很...
开发期间(代码样式/方法建议) 始终尝试使用单行if/else语句。 在那种情况下,不需要括号。 如果if/else表达式超过单行-请使用花括号。 如果仅使用if且表达式为单行-则不需要大括号。 private fun ...
基于XMPP协议,很多人都建议使用这个,谷歌官方的C2DM也是基于XMPP研发的,使用这个方案不会依赖android系统,也不依赖于谷歌服务器。 •XMPP协议比较费电费流量,对当前智能机的消耗太大 •在窄带网络和不稳定的...
开发了一个Android应用程序来跟踪我一周内的卡路里摄入量。 该应用程序还使用此数据来预测体重增加/减少,并提供实现目标的建议 要求 用户应输入一周中每一天的最大卡路里摄入量(目标) 使用者应输入食物的名称,...
为了解决这个问题,我们建议采用持续交付的方法,通过拥有自动化功能和单元测试的测试套件。 开发人员大多将测试技术的时间限制和高学习曲线归咎于没有发布经过适当测试的应用程序。 calabash-trainer 应用程序专注...
CodeIgniter使您可以最大限度地减少给定任务所需的代码量,从而创造性地专注于您的项目。发布信息此存储库包含将来版本的开发中代码。 要下载最新的稳定版本,请访问页面。变更日志和新功能您可以在 找到每个版本的...
”在此之前,谷歌已经推出了手机操作系统Android,另外,数款上网本也使用了这款操作系统。 长期以来,谷歌一直致力于计算机软件对于互联网的兼容性,以取代以计算机为中心的软件开发方式。谷歌希望,能够开发出...
我希望在开发或建议时使用任何新的“剪切”或相关技术来使此仓库保持最新状态。 如果有任何问题,想法或“削减”,请提出问题。 〜AK原始剪裁<!-- IE 9+, FF 8+, Opera 12, Chrome 29+, Android ~4.4+ Chrome 29...
嵌入式影子页表(ESPT)方法已建议有效减少此地址转换成本。 ESPT直接将GVA映射到HPA,从而避免了冗长的访客虚拟到访客物理,访客物理到主机虚拟主机和虚拟主机来托管物理地址转换。 但是,原始的ESPT工作有一些...
我们认为ZXScanLib和CAMView有很多共同点(此外,ZXScanLib依赖于CAMView),因此将其作为一个单独的可靠项目可以提高生产率,增加透明度并减少错误数量。 所有以前的ZXScanLib版本都将永久保留在Maven存储库中,...
开发人员、爸爸、妈妈、妈妈开发人员、爸爸开发人员、游戏开发人员、嵌入式系统工程师、家庭自动化公司:查找或索取存储库,克隆它并开始使用! 这里有一些建议: 谁将成为第一个发布带有内置家长控制功能的 iPhone ...
此应用程序的开发是为愿意在COVID-19危机期间向一群人(甚至全国!)提供工具或伴侣的志愿者和组织的起点。 该项目的灵感来自“ 一起的advice_app建议。 产品特点 开箱即用的它提供了五个主要功能: Newsfeed ,以...