導航:首頁 > 操作系統 > android播放幀動畫

android播放幀動畫

發布時間:2023-01-30 12:41:44

android幀動畫/AnimationDrawable導致的OOM/ANR的解決方案

如果有播放超多幀動畫的需求,直接點擊 FrameAnimation 在github查看,基本能滿足你的所有需求,就不用往下看了,基本能滿足 99.99% 人的需求。

       當在應用中需要使用幀動畫的時候,最先想到的就是Android提供的AnimationDrawable了,但是如果幀動畫中如果包含上百幀圖片,此時再用AnimationDrawable就不是那麼理想了。AnimationDrawable使用一個Drawable數組來存儲每一幀的圖像,會直接把全部圖片載入進內存。隨著幀數量的增多,就算性能再強勁的機器也會卡頓、OOM。

    最近的項目中需要用到大量的幀動畫(各種閃瞎24K鈦合金狗眼的禮物效果,多的高達200幀),既然AnimationDrawable不行,就想到了兩種解決方法。

   因為是直播的項目,包含人臉貼圖等都是用opengl繪制的,如果用OpenGL繪制一層Texture直接推流還省事。只在主播端處理就行了,但是IOS那邊都弄得差不多了,直接原生的不用處理也不會有什麼異常什麼的。。很尷尬。

    好吧,第一個不行那就想到Android自帶的surfaceView啦。我首先用不同的手機測試了下應用從本地decode一個bitmap的時間(png格式,414*736,大小在30-100k之間),因為幀動畫的每幀不會太大,在性能好點的設備上基本保持在10-30ms之間(不推流基本上推流狀態下10ms左右,推流狀態下20左右),在性能稍差的設備中基本上也不會超過50ms,所以說是沒什麼大問題的。

既然不能完全載入到內存,想到的就是類似視頻播放或者視頻直播類似的思路。首先定義一個Bitmap的緩沖區,邊繪制邊載入。首先載入一定數量的幀到Bitmap緩沖區,載入完成後通知SurfaceView開始繪制。SurfaceView繪制一幀完成後通知Bitmap緩沖區載入下一幀,同時將繪制過的一幀的從Bitmap緩沖區移除。一幀繪制完成後,繪制線程根據設置的幀間隔休眠一段時間,休眠完成後開始從Bitmap緩沖區獲取下一幀,依此類推,一直循環,直到播放完成或者手動停止。按照這種方式實現起來,發現oom卡頓什麼的果然不存在了,內存的使用情況如圖。

但是看著這個垃圾桶一個挨一個,這個內存回收情況完全不正常!GC太頻繁了。想著應該是這里出現了問題。[圖片上傳失敗...(image-96f387-1512626035688)]
頻繁的添加移除bitmap,導致了不算太嚴重的內存抖動。之所以稱之為不算太嚴重,因為大概400ms一次,一次gc花費2ms左右。不看內存,只看運行效果。真的感覺不出來。但是呢,這樣顯然也是不行滴。

最常見的解決方法就是對象的復用,創建各種pool。Android也提供了Bitmap的復用方式,在載入bitmap的時候傳入一個inBitmap,那麼載入的bitmap就會復用原bitmap的內存空間,所以理論上將要復用的bitmap和新載入的bitmap在顏色深度一樣的情況下,復用的bitmap寬高要大於新載入的bitmap。50L的桶畢竟最多隻能裝50L的水。關於inBitmap更多資料可以參考 這里 , 還有這里 。(請自備梯子)。 使用起來很簡單,大概就是這樣

然後實現思路就是在這里修改了,把將要刪除的哪一幀留下來作為inBitmap。

② 知識體系四:Android動畫工作原理

1.Android 動畫的工作原理?
在android系統中動畫分為兩種分別是幀動畫和屬性動畫。對於動畫的工作原理主要涉及到的是幀動畫的實現。
幀動畫主要有旋轉RotatleAnimation,縮放ScaleAnimation,透明AlphaAnimation,平移TranslateAnimation等都是Animation的子類。Animation控制動畫的效果,Transformation 對動畫進行計算。
對於動畫的原理簡單說就是從一個動畫的啟動狀態,到動畫結束狀態,和動畫持續總時間,在這段時間中任一時間點動畫的狀態計算和顯示的過程。
計算 :是通過Animation的getTransformation()方法首先對時間進行歸一化時間讓時間在0~1之間,進行計算。滿足條件之後就會調用applyTransformation()方法處理實現動畫類型的計算。當前時間點的轉換狀態保存到Transformation 的Matrix中等待顯示的時候使用。
顯示 :動畫顯示工作主要依賴於Choreograther類,此類是線程唯一的,Choreograther和Handler用法類似,都是通過post一個Runnable對象到隊列中等待VSYSC屏幕垂直同步信號刷新(16ms)刷新一次,然後觸發ViewRootImpl的view的遍歷工作,回調到view.draw()方法時就會把之前applyTransformation 計算的此時刻的Transformation 的Matrix賦值到Canvas上, 這也就是為什麼我們使用幀動畫時候我們的view的屬性並沒有改變,這就是根源因為計算得到的Matrix被Canvas使用了,並沒有直接賦值到我們的view上。 對於屬性動畫來說主要使用animator實現看下面解析:

2.Animation 和 Animator 的區別?
Animation和Animator都是抽象類,都有子類,Animation通過Transformation對動畫進行Matrix轉換來作用到Canvas上實現動畫效果。而Animator只是一個工具類,主要是用來控制在一段時間內某一個值的變化過程,然後我們再根據這個值來作用到view的屬性上,以此來實現動畫效果。為了讓這個變化的過程能達到加速減速等變化效果系統提供了插值器Interpolator。他們的實現思想都是一致的。

3.幀動畫 和 屬性動畫的區別?

③ Android-幀動畫詳解

這篇文章來聊聊 Android 原生動畫的 幀動畫 ,通俗的理解就是把一張張圖片按照順序播放,達到一個動態的效果。希望我的這篇文章對看文章的小夥伴有所啟發。

android:oneshot=「false」 屬性說明:表示是否重復播放。

每個item都有 drawable 和 ration 屬性, drawable 表示我們要播放的圖片, ration 表示這張圖播放的時間。

④ Android 動畫詳解

  android中酷炫的效果,都離不開動畫的支持。這里我們詳細介紹一下android中動畫的分類。android的中動畫分為幀動畫、補間動畫、屬性動畫。原理各不相同,實現的效果也大不相同。下面一一講解三種動畫。

  幀動畫顧名思義就是通過順序一幀一幀播放圖片從而產生動畫效果,效果類似放電影。該動畫缺點比較明顯,就是如果圖片過大過多會導致OOM。幀動畫xml文件放置在drawable目錄下而非anim文件夾下。

  補間動畫是通過對view進行旋轉、縮放、漸變、透明度變化,而達到的一種動畫效果。是一種漸進式動畫。並且可以通過組合以上四種操作,完成復雜的自定義動畫效果。缺點就是只是改變的view的展示狀態,但是不會改變view的位置。例如我們將一個button通過位移想左移動100dp,然後停留在終點。但是我們可以發現展示的位置button點擊無效果,不可以交互。而在button原始位置空白的地方點擊會觸發button的點擊效果。也就是button本質還是在原來位置,只是展示左移了100dp。

透明度動畫,通過改變view的透明度展示動畫。對應AlphaAnimation和<alpha>xml標簽

縮放動畫,通過修改view的大小展示動畫。對應ScaleAnimation類和<scale>xml表情

通過旋轉view展示動畫。對應RotateAnimation類和<rotate>xml標簽

平移動畫,更改view的展示位置展示動畫。對應TranslateAnimation類和<translate>xml表情

應用動畫xml配置

使用java類配置動畫,具體參數類同xml參數,建議使用xml配置動畫

  屬性動畫本質是通過改變對象的屬性(例如:x,y等屬性),來實現動畫的,所以基本上是無所不能的,只要對象有這個屬性,就能實現動畫效果。屬性動畫是在api11的新特性,通過動態的改變view的屬性從而達到動畫效果。雖然可以使用nineoldandroid庫向下兼容,但是兼容本質是使用補間動畫完成,也就是說不會更改view的屬性,也不會更改view的位置。屬性動畫比較常用的類: ValueAnimator、ObjectAnimator、AnimationSet,其中ObjectAnimator是ValueAnimator的子類,而AnminationSet是動畫集合

動畫配置同樣可以使用xml配置,參數類似,這里不做詳細說明。

根據時間流逝百分比計算當前屬性改變百分比。同xml配置動畫中的 android:interpolator 屬性配置,常見有LinearInterpolator(線性差值器)、(加速減速差值器)
等。自定義需要實現 Interpolator 或者 TimeInterpolator 。Interpolator介面繼承TimeInterpolator。

根據當前屬性改變百分比計算改變後的屬性值。屬性動畫特有的屬性。自定義估值器需要實現 TypeEvaluator 介面。

可以對任意屬性做屬性動畫,屬性動畫要求動畫作用的對象提供該屬性的get()和set()方法。因為屬性動畫本質就是根據外界傳遞的對象屬性的初始值和終點值,然後根據估值器和差值器計算屬性值,不斷調用屬性的set方法,通過時間的推移所傳遞的值,越來越近終點值。
注意:

使用ValueAnimator通過監聽動畫過程,自己改變對象屬性完成動畫

⑤ Android如何將逐幀動畫加在界面上

動畫的使用 是 Android 開發中常用的知識
可是動畫的 種類繁多、使用復雜 ,每當需要 採用自定義動畫 實現 復雜的動畫效果 時,很多開發者就顯得束手無策
本文將詳細介紹 Android 動畫中 逐幀動畫 的原理 & 使用
#1. 作用對象 視圖控制項( View )
1. 如 Android 的 TextView、Button 等等
2. 不可作用於 View 組件的屬性,如:顏色、背景、長度等等
#2. 原理
將動畫拆分為 幀 的形式,且定義每一幀 = 每一張圖片
逐幀動畫的本質:按序播放一組預先定義好的圖片
#3. 具體使用 ####步驟1:將動畫資源(即每張圖片資源)放到 drawable 文件夾里
技巧:
1. 找到自己需要的gif動畫
2. 用 gif 分解軟體(如 GifSplitter )將 gif 分解成一張張圖片即可

⑥ Android 幀動畫何時停止播放

可以通過一些其他方式來做到。
方式一,當動畫開始start之後,我們可以通過檢測是否到達幀動畫的最後一幀,來確定動畫是否播完。這種方式可以保證動畫播完。
方式二,重寫AnimationDrawable,獲得totalDuration,然後動畫start之後的totalDuration,調用結束的介面回調onAnimationFinshed()。為什麼必須重寫呢?因為,AnimationDrawable僅提供了每一幀的ration,而不能直接獲得動畫總的ration。
當然還有一些變種的方法,但是其大體思路都應該差不多。至於動畫是否流暢播放,這要取決於你播放動畫的時候,系統的繁忙程度。

⑦ android幀動畫 可以設置在什麼組件上

先在res目錄下(或anim目錄)創建一個XML,裡面保存每個圖片的信息
/res/anim/loading.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list
android:oneshot="false"
xmlns:android="http://schemas、android、com/apk/res/android"
>

<item android:ration="150" android:drawable="@drawable/recording1" />
<item android:ration="150" android:drawable="@drawable/recording2" />
<item android:ration="150" android:drawable="@drawable/recording3" />
<item android:ration="150" android:drawable="@drawable/recording4" />
<item android:ration="150" android:drawable="@drawable/recording5" />
<item android:ration="150" android:drawable="@drawable/recording6" />
<item android:ration="150" android:drawable="@drawable/recording7" />

</animation-list>

animation-list標簽就代表,這是一組動畫的列表
android:oneshot屬性,表示循環播放,true則只播放一次,false表示循環一直播放。
item標簽代表各個幀元素
android:ration屬性代表幀與幀之間的持續時間,以毫秒為單位
android:drawable屬性代表具體的圖片信息。

⑧ 請問一下Android怎麼設置幀動畫的播放時間啊注意是幀動畫哦~~

表示關注,AnimationSet 好像只能實現樓主說的四種補間動畫的組合。幀動畫AnimationDrawable加不進去。實在不行就等幀動畫結束時在調用AnimationSet 。。 AnimationSet 的public void addAnimation(Animation a)只能...

⑨ android逐幀動畫

在配置中填寫 android:oneshot="true" 播放一次

閱讀全文

與android播放幀動畫相關的資料

熱點內容
海康攝像螢石雲伺服器 瀏覽:814
安卓手機怎麼改安卓版名 瀏覽:147
雅思聽力807詞彙pdf 瀏覽:897
黃豆私人加密 瀏覽:192
java分鍾轉換小時 瀏覽:245
易語言伺服器如何提高 瀏覽:591
網站主機伺服器地址查看 瀏覽:859
演算法學不會能當程序員嗎 瀏覽:119
程序員技術交流研究 瀏覽:814
javaresponse文件 瀏覽:734
linuxrar壓縮文件夾 瀏覽:218
魅藍手機連接不上伺服器怎麼回事 瀏覽:379
工行app怎麼改已綁定銀行卡 瀏覽:533
oppo晶元程序員 瀏覽:602
oppok3應用怎麼加密 瀏覽:327
電腦軟盤怎麼加密碼 瀏覽:815
伺服器光交換機有什麼用 瀏覽:708
app上怎麼拍蛙小俠 瀏覽:217
志高聊天app怎麼下載 瀏覽:635
郵政app怎麼不能掃付款碼 瀏覽:559