Android-Lint工具使用

shenguopin 8年前發布 | 13K 次閱讀 安卓開發 Android Studio開發工具

公司的項目之前是幾乎是純原生開發,后來因業務需求變更過于頻繁,加上原生開發成本較高,后來采用了混合開發模式,絕大部分頁面采用了H5頁面,因此之前使用的資源文件(包括圖片,xml文件等)大部分被閑置。近段時間,項目成立了專門的優化工作組,清理無用資源,壓縮apk體積也被納入此次優化工作范圍。在做資源清理的時候無可避免的用到了Android-Lint,本文主要講述Android-Lint的使用以及使用中的一些注意事項。

Android-Lint是SDK Tools 16 (ADT 16)之后才引入的工具,通過代碼檢查,可發現潛在的問題,并能對Android程序進行優化處理。在AndroidStudio中已經集成了該工具,下面直接演示使用方法。

如圖,在頂部菜單欄找到Analyze選項,在彈框中選中Inspect Code,或者對項目根雙擊彈出菜單彈框(windows下右鍵項目根目錄),找到Analyze選項再選中Inspect Code選項,可以見到下圖對話框

選中whole project,然后直接選擇OK按鈕,你會見到以下進度條

靜靜地等待,等待時間由你的項目大小和你的機器性能有關,檢查完畢后會彈出Inspection的控制臺

如圖所示,看著你可能會一臉懵逼了(點擊每一項進去還有一大堆子項,你可能會直接暈菜),不過不用急,下面來簡單解釋以下以Android->Lint開頭中一些重的子項的意義,我的初衷是清理無用資源,我用粗體標記了哪些是對此次任務有重要意義的子項。

  1. Correctness
    1) DuplicatedIds
    Layout中id應該唯一
    2) NewApi
    代碼中使用的某些API高于Manifest中的Min SDK
    3) InconsistentArrays
    字符串國際化中,同一名字的的String-Array對應的item值不相同
    4) Registered
    Activity/Service/ContentProvider沒有通過AndroidManifest注冊
    5) Deprecated
    使用已經廢棄的API
    6) PxUsage
    避免使用px,使用dp
  2. Correctness:Messeges
    1) MissingTranslation
    字符串國際化不完全
    2) ExtraTranslation
    國際化的字符串,在默認位置(defaultlocale),沒有定義
  3. Security
    1) SetJavaScriptEnabled
    不確定你的程序中確實需要JavaScript就不要執行SetJavaScriptEnabled。
    2)ExportedContentProvider/ExportedReceiver/ExportedService/ExportedActivity
    ContentProvider/Receiver/Service/Activity的exported為true時,設置一個Permission,讓使用者獲取了Permission才能使用。
    3) HardcodedDebugMode
    不要在manifest中設置android:debuggable。
    設置它,編譯的任何版本都要采用指定的debug模式。不設置,編譯Eng版本采用debug模式;編譯User版本采用release模式。
    4. Performance
    1) DrawAllocation
    避免在繪制或者解析布局(draw/layout)時分配對象。E.g.,Ondraw()中實例化Paint對象。
    2) ObsoleteLayoutParam
    Layout中無用的參數。
    3) UseCompoundDrawables
    可優化的布局:如包含一個Imageview和一個TextView的線性布局,可被采用CompoundDrawable的TextView代替。
    4) UseSparseArrays
    盡量用Android的SparseArray代替Hashmap
    5) DisableBaselineAlignment
    如果LinearLayout被用于嵌套的layout空間計算,它的android:baselineAligned屬性應該設置成false,以加速layout計算。
    6) FloatMath
    使用FloatMath代替Math。
    7) NestedWeights
    避免嵌套weight,那將拖累執行效率
    8) UnusedResources/UnusedIds
    未被使用的資源會是程序變大,并且編譯速度降低。 **
    9) Overdraw
    如果為RootView指定一個背景Drawable,會先用Theme的背景繪制一遍,然后才用指定的背景,這就是所謂的“Overdraw”。
    可以設置theme的background為null來避免。
    10) UselessLeaf/UselessParent
    View或view的父親沒有用
    11)Handler Reference leaks
    handler可能導致的內存泄漏
  4. Usability:Typography
    1) TypographyDashes
    特殊字符需用編碼代替:“–”需要用“–”;“—”需要用“—”
    2) TypographyEllipsis
    特殊字符需用編碼代替:“…”需要用“…”
    3) TypographyOther
    問題:“(c)”需要用“?”
  5. Usability:Icons
    1) IconNoDpi
    Icon在nodpi和指定dpi的目錄下都出現。
    2) GifUsage
    Image不要用GIF,最好用PNG,可以用JPG。
  6. Usability
    1) BackButton
    Android中不要設計有Back的按鈕,Android中一般有Back的硬按鍵。
    2) ButtonCase
    Button的“Ok”/“Cancel”顯示大小寫一定,不要全大寫或全小寫。有標準的資源的字符串,不要自己再定義,而要用系統定義的:@android:string/ok和@android:string/cancel
  7. Accessibility
    1) ContentDescription
    ImageView和ImageButton應該提供contentDescription
  8. Internationalization
    1) HardcodeText
    硬編碼的字符串應該在資源里定義
    2) EnforceUTF8
    所有XML資源文件都應該以UTF-8編碼

UnusedResources 是我此次代碼檢查的目的,檢測顯示我的項目中有1000多item是未被使用的,選中其中一個xml文件

發現有個Remove All Unused Resources的選項,大喜過望,感覺這項工作so easy,馬上點擊,運行完畢,clean一下,臥槽,報錯,為什么。。。

檢查報錯代碼,發現是內部的安全鍵盤sdk找不到指定id,真是神奇了,不是說好的無用資源嗎?為什么會報錯。突然發現,安全鍵盤對資源文件的調用采用了反射的模式去調用,因為需要它作為一個sdk打包成了jar包,jar包中只包含了它的src中的代碼文件,資源文件也沒有打包,認識直接放到宿主項目的相應文件夾下,使用的時候采用反射的模式進行調用。此時恍然大悟,lint工具會將沒有被直接引用的東西都標記成了無用的。這應該也算是它的一個坑吧。想過先全部清理,然后在把sdk的資源文件放回原位,但是檢查發現還有好幾個早期的內部sdk采用了將資源文件直接放到宿主項目的相應文件夾的做法,難度較大,而且這種隱蔽的東西很難控制,最后只能一個個去刪除,但也只是刪除了一部分,做不到徹底刪除。不過lint工具還是提供了很好的參考。最后將原本將近5M的資源文件刪至3.5M左右,再清理掉一些無用的jar包和so庫,左右將apk的體積壓縮了大概8M左右。

上面還有一個值得注意的地方就是 Handler Reference leaks, 即是 handler可能導致的內存泄漏。 可能是項目早期缺乏考慮,加上很多代碼是外包人員編寫,或許是責任心不夠強,項目中使用的handler大部分是內部類,當使用內部類(包括匿名類)來創建Handler的時候,Handler對象會隱式地持有一個外部類對象(通常是一個Activity)的引用(不然你怎么可能通過Handler來操作Activity中的View?)。而Handler通常會伴隨著一個耗時的后臺線程(例如從網絡拉取圖片)一起出現,這個后臺線程在任務執行完畢(例如圖片下載完畢)之后,通過消息機制通知Handler,然后Handler把圖片更新到界面。然而,如果用戶在網絡請求過程中關閉了Activity,正常情況下,Activity不再被使用,它就有可能在GC檢查時被回收掉,但由于這時線程尚未執行完,而該線程持有Handler的引用(不然它怎么發消息給Handler?),這個Handler又持有Activity的引用,就導致該Activity無法被回收(即內存泄露),直到網絡請求結束(例如圖片下載完畢)。另外,如果你執行了Handler的postDelayed()方法,該方法會將你的Handler裝入一個Message,并把這條Message推到MessageQueue中,那么在你設定的delay到達之前,會有一條MessageQueue -> Message -> Handler -> Activity的鏈,導致你的Activity被持有引用而無法被回收。這個問題也是較常見的可能導致內存泄漏的問題,解決方法一般是通過弱引用持有對Activity的引用,具體的實現方式自行百度或者google吧。最后順手點個贊,再順便掃掃碼關注我的公眾號(原諒我的不知足。。。),所有文章都會在公眾號發布。

?

 

來自:http://www.jianshu.com/p/010f895fe2cc

 

 本文由用戶 shenguopin 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!