標籤:content tar 記憶體 wrap one tag his 源檔案 asc
2015年項目接到一個需求,實現一個嚮導動畫,這個動畫一共六十張圖片,當時使用的是全志A33的開發板,通過使用Android的動畫集實現,效果特別卡頓,然後想到這種方式來實現,效果很流暢.然後寫成開一個開源項目供大家參考
通過以下兩種方式實現幀動畫,使用相同的80張280x280的png圖片執行動畫,資源佔用情況對比:
代碼地址:
https://github.com/ansen360/FrameAnimation
Sample效果:
http://oma689k8f.bkt.clouddn.com/note/3/4.gif
Android動畫集實現幀動畫
- 1 在drawable目錄下建立動畫集animalist.xml
<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <!--通過Android動畫集播放的八十張圖片--> <item android:drawable="@mipmap/c_1" android:duration="50" /> <item android:drawable="@mipmap/c_2" android:duration="50" /> <!-- 省略... --> <item android:drawable="@mipmap/circle_19" android:duration="50" /> <item android:drawable="@mipmap/circle_20" android:duration="50" /></animation-list>
- 2 在布局檔案ImageView中使用該drawable
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 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="com.ansen.frameanimation.sample.MainActivity"> <ImageView android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/animlist" /></LinearLayout>
ImageView image = (ImageView) findViewById(R.id.image); AnimationDrawable animationDrawable = (AnimationDrawable) image.getDrawable(); animationDrawable.start();
動畫啟動系統資源佔用情況如下:
手動觸發GC,記憶體佔用幾乎沒改變
FrameAnimation實現幀動畫
- 1 定義需要播放動畫的資源檔;在arrays檔案中定義資源,或者在代碼中定義
<?xml version="1.0" encoding="utf-8"?><resources> <!--通過FrameAnimation播放的八十張圖片--> <array name="c"> <item>@mipmap/c_1</item> <item>@mipmap/c_2</item> <!-- 省略... --> <item>@mipmap/circle_19</item> <item>@mipmap/circle_20</item> </array></resources>
擷取定義之後的資源數組(代碼中可直接定義資源檔的數組,便可忽略上一步):
private int[] getRes() { TypedArray typedArray = getResources().obtainTypedArray(R.array.c); int len = typedArray.length(); int[] resId = new int[len]; for (int i = 0; i < len; i++) { resId[i] = typedArray.getResourceId(i, -1); } typedArray.recycle(); return resId; }
ImageView image = (ImageView) findViewById(R.id.image); FrameAnimation frameAnimation = new FrameAnimation(image, getRes(), 50, true); frameAnimation.setAnimationListener(new FrameAnimation.AnimationListener() { @Override public void onAnimationStart() { Log.d(TAG, "start"); } @Override public void onAnimationEnd() { Log.d(TAG, "end"); } @Override public void onAnimationRepeat() { Log.d(TAG, "repeat"); } });
動畫啟動系統資源佔用情況如下:
手動觸發GC,記憶體佔用有明顯變化
Android幀動畫實現,防OOM,比原生動畫集節約超過十倍的資源