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.pswp.cn/news/539868.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/539868.shtml
英文地址,請注明出處:http://en.pswp.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…