android开发方法数,Android减少App方法数

作为Android开发者我们都知道Android应用方法数65535这样一个限制,这是因为在Android系统中,方法的id使用short类型存储在Dex文件中,而short类型的取值范围是-32,768到32,767,因此导致Android应用方法数65535这样一个最大限制,超过这个方法是打包就会失败,也可以使用MultiDexApplication来解决,但这不是最优的解决方案,也可是用插件化来解决这个问题(稍后我会分享插件化),个人觉得最好是在开发中尽量避免这样的问题。

1.为什么要减少方法数

这要从dex的文件格式说起,在把源码编译、转化为dex文件格式时,dex文件中会有一个区域包含了所有源码中定义或引用的方法列表。这个区域中所有方法项的总数就是方法数。

Android在刚开始被设计的时候,这一区域的方法数量不能超过65536个,也就是2个字节表示的范围。当源码定义或引用的方法数量超过了这个限制的话,就会导致编译不成功,你说重要不重要呢?

2.如何查看这些方法?

dexdump 命令:

查看apk的method总数  dexdump  -f  app.apk | grepmethod_ids_size

查看apk的field总数dexdump  -f  app.apk | grepfield_ids_size

查看apk的method详情  dexdump -f  app.apk

可以使用修改过的dexdump。标准的dexdump可以解析方法列表,但无法打印出来,修改版的dexdump可以打印这些信息

如下是一个简单类LogicActivity中使用的方法

Class: Lcom/xxx/activity/LogicActivity; 18

Method: ()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: ()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: ()V

Method: onCreate (Landroid/os/Bundle;)V

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/539868.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

内表,外表

一、内表 Internal Table 内表与结构体基本类似,它同样是程序运行中被临时创建的一个存储空间,它是一个可包含多条记录的数据表。 二、外表 外表(external table)就像普通的表对像一样,可以select等,只是它是只读的,数…

国外分享插件

<script type"text/javascript" src"//s7.addthis.com/js/300/addthis_widget.js#pubidra-59effacb0a4e93a8"></script> addthis转载于:https://www.cnblogs.com/ghfjj/p/8026946.html

android 方法超时,android socket.io中的发出或确认超时处理?

套接字发出超时确认我的AckWithTimeOut带有实现的自定义超时类Ack接口public class AckWithTimeOut implements Ack {private Timer timer;private long timeOut 0;private boolean called false;public AckWithTimeOut() {}public AckWithTimeOut(long timeout_after) {if (…

2017 Google 开发者大会直播入口

今年&#xff0c;Google 开发者大会再度来袭&#xff01;大会将于 12 月 13 日和 14 日在上海举办&#xff0c;主题涵盖机器学习 (Machine Learning)、Android、移动网络&#xff08;Mobile Web)、TensorFlow、Firebase、云服务 (Cloud)、AR/VR、设计 (Design) 以及更多开发者相…

Oracle sqlldr

一、sqlldr的概述 sqlldr是oracle自带的一个工具&#xff0c;用于导入文本文件的内容到oracle数据库中。 该工具在&#xff1a;\oracle\app\oracle\product\11.2.0\server\bin\sqlldr.exe 二、使用 D:\oracle\app\oracle\product\11.2.0\server\bin\sqlldr.exe useriduser/…

android实现推送方式解决方案,Android实现推送方式解决方案系列教程

Android实现推送方式解决方案系列教程 1-5Android实现推送方式解决方案系列教程总结者&#xff1a;难民 交流Q群: 137824028Android实现推送方式解决方案系列之一--XMPP协议出自&#xff1a;http://doc.docsou.com/thread-1004-1-1.htmlXMPP协议简介XMPP(Extensible Messageing…

日志组件slf4j介绍及配置详解

2019独角兽企业重金招聘Python工程师标准>>> 原文出自 1 基本介绍 每一个Java程序员都知道日志对于任何一个Java应用程序尤其是服务端程序是至关重要的&#xff0c;而很多程序员也已经熟悉各种不同的日志库&#xff0c;如java.util.logging、Apache log4j、logback。…

count(*),count(1),count(0)效率

网上文章很多&#xff0c;今天分别跑了一张2000多万行的表&#xff0c;该表没有主键&#xff0c;索引&#xff0c;约束条件。 结果是&#xff0c;效率差不多

android 转场动画兼容问题,【Android】关于ARouter转场动画的问题

实现从主页跳转到搜索页&#xff0c;再从搜索页回退主页withTransition(int resId,int resId)这个方法两个参数第一个的意思是&#xff0c; A 到 B&#xff0c; B 的入场动画第二个的意思是&#xff0c;A 到 B&#xff0c; A 的出场动画即&#xff0c;入场动画&#xff0c;出场…

Oracle 一些常用函数

ROUND&#xff1a; 如何使用 Oracle Round 函数 (四舍五入) 描述 : 传回一个数值&#xff0c;该数值是按照指定的小数位元数进行四舍五入运算的结果。 SELECT ROUND( number, [ decimal_places ] ) FROM DUAL 参数: number : 欲处理之数值 decimal_places : 四舍五入 , 小数取…

基于github和hexo搭建博客 本地hexo博客搭建

正常都应该讲一讲为什么搭建博客&#xff0c;不过既然您能看见这篇文章&#xff0c;就说明你想搭建一个自己的博客&#xff0c;无论自己记录自己的东西&#xff0c;或是为了显得高大上。那就不废话了&#xff0c;进入正题。 其实教大家搭建博客的文章很多&#xff0c;讲的都不错…

react不同环境不同配置angular_叫雨山斗鸡优势在哪里,环境不同,价值不同

叫雨山斗鸡优势在哪里&#xff0c;环境不同&#xff0c;价值不同 原生态高端食材网站&#xff0c;专注金线莲、散放斗鸡、斗鸡蛋、野生蜂蜜、小耳黑猪肉等云南原生态套餐定制的高端食材供应商。云南叫雨山斗鸡叫雨山斗鸡原生态饲养 叫雨山斗鸡源自于鲁西斗鸡&#xff0c;初代斗…

android studio 布局拖拽,为什么使用android studio不能像老师一样在Design里随意拖动控件...

qq_喷泉_02017-07-25 13:08已采纳xmlns:app"http://schemas.android.com/apk/res-auto"xmlns:tools"http://schemas.android.com/tools"android:layout_width"match_parent"android:layout_height"match_parent"tools:context"co…

Oracle自定义函数(不断更新)

1、将数字转为ip地址&#xff1a;IPAdd_DotNumFormat create or replace FUNCTION IPAdd_DotNumFormat(v_LfValue number)return varchar2 asv_DotNumString varchar2(50);v_flg Integer;v_NewLfValue number;v_tmp Integer;v_P1 Integer;v_P2 Integer;v_P3 Integer;v_P4…

element ui select设置不显示不存在的项_appium—等待时间设置方法

引言&#xff1a;在做UI自动化的过程中&#xff0c;我们有时候为了等待元素的出现&#xff0c;需要加一些等待时间来帮助&#xff0c;但是有时候时间加的过多或者过少&#xff0c;这个没有办法判断&#xff0c;今天就介绍几种等待时间&#xff0c;我们看看那种适合我们 一、强制…

android rn 和webview,RN Webview与Web的通信与调试

React Native Version:0.51RN 在 0.37 版本中加入了WebView功能&#xff0c;所以想要在使用WebView,版本必须>0.37&#xff0c;发送的 message 只能是字符串&#xff0c;所以需要将其他格式的数据转换成字符串&#xff0c;在接收到后再转换回去&#xff0c;其实直接用JSON.s…

数据库完整性检查

为了主动发现数据库侧页损坏&#xff0c;保证数据库逻辑和物理完整性&#xff0c;计划每周六上午6点&#xff0c;针对生产主库上的所有系统和用户数据库执行DBCC CHECKDB&#xff0c;将结果记录到表中。以下为理论依据&#xff1a;SQL Server数据库可以检测出页损坏&#xff0c…

GNU概念

一、GNU的意思 GNU的全称&#xff1a;GNU is not unix&#xff0c;意思是&#xff1a;GNU 不是 unix 问&#xff1a;为什么这样取名&#xff1f; 答&#xff1a;为了打造一个不是unix又类unix的系统 二、GNU的历程 GNU计划是由Richard Stallman 在1984年公开发起的&#x…

Item 13 Minimize the accessibility of classes and members

区分好的模块和不好的模块最重要的因素是看这个模块对于其他模块而言是否隐藏内部数据和其他细节。好的模块会把所有细节隐藏起来&#xff0c;把API和实现隔离开来&#xff0c;模块之间用API通信。这就是information hiding或者封装(encapsulation)。是软件设计基本原则之一。 …

html 物流状态,使用css实现物流进度的样式的实例代码

效果&#xff1a;css样式&#xff1a;ul li {list-style: none;}.package-status {padding: 18px 0 0 0}.package-status .status-list {margin: 0;padding: 0;margin-top: -5px;padding-left: 8px;list-style: none;}.package-status .status-list>li {border-left: 2px so…