Android軟體開發中常見的幾個瓶頸
不同解析度適配
不同版本調試
語言?效能?觸摸?動畫?
記憶體,記憶體,記憶體...
Android軟體記憶體限制
Android系統對每個軟體所能使用的RAM空間進行了限制(如: Nexus one 對每個軟體的記憶體限制是24M)
Java語言本身比較消耗記憶體
dalvik虛擬機器也要佔用一定的記憶體空間
OOM功臣—Bitmap
當在Android手機上直接讀取4M的圖片時,死神一般都會降臨
往往自己手機拍攝的照片都不能直接讀取
OOM功臣—Bitmap
技巧:讀取圖片之前先查看其大小
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(imageFile, opts);
使用得到的圖片原始寬高計算適合自己的smaplesize
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeFile(imageFile, opts);
OOM功臣—Bitmap
對於過時的Bitmap對象一定要及時recycle
並且把此對象賦值為null
bitmap.recycle();
bitmap = null;
View最佳化
使用9patch格式的圖片資源
使用png圖片壓縮公用程式對9patch格式圖片壓縮
使用-land, -mdpi, -hdpi等作為layout和當然啊wable的尾碼,來做圖片適應和不同解析度適配
View最佳化
使用layoutopt進行最佳化
$ layoutoptsamples/ samples/compound.xml
The root-level <FrameLayout/> can be replaced with <merge/>
This LinearLayoutlayout or its FrameLayoutparent is useless samples/simple.xml
The root-level <FrameLayout/> can be replaced with <merge/> samples/too_deep.xml
This layout has too many nested layouts: 13 levels, it should have <= 10!
參考http://android-developers.blogspot.com/2009/11/optimize-your-layouts.html
減少邏輯代碼工作量
class MyActivityextends Activity {
public void myClickHandler(View v) {
// Do stuff
} }
在Layout xml檔案中加入:
<Button android:onClick="myClickHandler" />
即可實現不在代碼中建立OnClickListener
使用最少的View
LinearLayoutxmlns:android=“http://schemas.android.com/apk/res/android” android:layout_width=“fill_parent” android:layout_height=“?android:attr/listPreferredItemHeight” android:padding=“6dip”>
<ImageViewandroid:id=“@+id/icon” android:layout_width=“wrap_content” android:layout_height=“fill_parent” android:layout_marginRight=“6dip” android:src=“@drawable/icon” />
<LinearLayoutandroid:orientation=“vertical” android:layout_width=“0dip” android:layout_weight=“1” android:layout_height=“fill_parent”>
<TextViewandroid:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" android:gravity="center_vertical" android:text="My Application" />
<TextViewandroid:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" android:singleLine="true" android:ellipsize="marquee" android:text="Simple application that shows how to use RelativeLayout" />
</LinearLayout>
</LinearLayout>
去掉不必要的View
<resources>
<style name="Theme.NoBackground" parent="android:Theme">
<item name="android:windowBackground">@null</item> </style>
</resources>
在Manifest.xml的Activity或Application中添加android:theme="@style/Theme.NoBackground"
減小圖片大小
res/drawable/background_shelf.xml中使用:
<bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/shelf_panel" android:tileMode="repeat" />
使用Stub
A ViewStub is an invisible, zero-sized View that can be used to lazily inflate layout resources at runtime
<ViewStub android:id="@+id/stub" android:inflatedId="@+id/subTree" android:layout="@layout/mySubTree" android:layout_width="120dip" android:layout_height="40dip" />
ViewStub stub = (ViewStub) findViewById(R.id.stub);
View inflated = stub.inflate();
代碼級記憶體最佳化
Android提供了很健全的訊息傳遞機制(Intent)和任務模型(Handler),可以通過傳遞或事件的方式,防止一些不必要的全域變數
對於很多必不可少的全域引用,如果不是隨時需要或者必不可少,則可以使用SoftRerence 或者 WeakRerence引用他們,可以保證在系統記憶體不足的時候,他們會首先釋放而不是出現OOM
如果有牽涉到大量對象或者組合資料的演算法操作,則最好使用C語言封裝這些對象並進行操作,通過jni調用至於java語言進行最簡單的資料通訊。因為即使空的JAVA語言對象也會佔據20多個位元組
Android軟體效能最佳化淺談
Android效能殺手:
1. GC, 系統GC之低效
2. layout布局和view顯示
3. load圖片和檔案讀取
Android軟體效能最佳化淺談
提升效能的幾點技巧:
1. 減少臨時對象的頻繁產生和銷毀
2. 使用ViewStub消極式載入某些比較複雜的layout
3. 迴圈或者多層迴圈內的操作儘可能簡單,更能享受jit帶來的加速
4. 佔用CPU較多的資料操作儘可能放在一個單獨的線程中進行,通過handler等方式把執行的結果交於UI線程顯示
小結
Android系統中處處可見生命週期的使用,包括activity,view等等。此種做法線上程同步等方面有很積極的意義,並且對程式執行的階段有很清晰的劃分。
我們只要嚴格按照Android程式執行的生命週期,在處理記憶體消耗型任務時,使用壓縮,緩衝和流等方式,在處理cpu消耗型任務時採用額外線程處理,UI線程展示的方式,就可以在編寫Android程式時避免很多古怪的問題。