1. 程式人生 > >仿Uber啟動---完美解決幀動畫播放oom異常

仿Uber啟動---完美解決幀動畫播放oom異常

仿照uber啟動的視屏,uber解壓以後,其實就是一個連續播放的多張圖片形成的動畫,接著就是一段Mp4 的視訊迴圈播放。

android幀動畫一般是採用animation-list 如果圖片很小,那麼可以解決,但是遇到圖片過大就處理不了了開發的時候發現uber這個軟體的啟動動畫是幀動畫和一個mp4視訊,但是幀動畫在iOS是行得通但是在android同樣原理處理會出現oom異常,uber的android版本也沒有這個啟動動畫,不知道是不是因為記憶體無法及時釋放的原因猜沒有加進去,下面的方法就完美解決了這一問題,因為缺少幾張圖片,所以和uber有點不同,這沒什麼太大關係,下面是幀動畫載入過多oom

問題的方案

行不通的方案:連續播放的67張圖片,res/anim/frame_animation.xml。

<animation-list  xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true">
    <item android:drawable="@drawable/a_0"  android:duration="50"/>
    <item  android:drawable="@drawable/a_0"  android:duration="50"/>
    <item  android:drawable="@drawable/a_1"  android:duration="50"/>
    <item  android:drawable="@drawable/a_2"  android:duration="50"/>
    <item  android:drawable="@drawable/a_3"  android:duration="50"/>
    <item  android:drawable="@drawable/a_4"  android:duration="50"/>
    <item  android:drawable="@drawable/a_5"  android:duration="50"/>
    <item  android:drawable="@drawable/a_6"  android:duration="50"/>
    <item  android:drawable="@drawable/a_7"  android:duration="50"/>
    <item  android:drawable="@drawable/a_8"  android:duration="50"/>
    <item  android:drawable="@drawable/a_9"  android:duration="50"/>
    <item  android:drawable="@drawable/a_10"  android:duration="50"/>
    <item  android:drawable="@drawable/a_11"  android:duration="50"/>
    <item  android:drawable="@drawable/a_12"  android:duration="50"/>
    <item  android:drawable="@drawable/a_13"  android:duration="50"/>
    <item  android:drawable="@drawable/a_14"  android:duration="50"/>
    <item  android:drawable="@drawable/a_15"  android:duration="50"/>
    <item  android:drawable="@drawable/a_16"  android:duration="50"/>
    <item  android:drawable="@drawable/a_17"  android:duration="50"/>
    <item  android:drawable="@drawable/a_18"  android:duration="50"/>
    <item  android:drawable="@drawable/a_19"  android:duration="50"/>
    <item  android:drawable="@drawable/a_20"  android:duration="50"/>
    <item  android:drawable="@drawable/a_21"  android:duration="50"/>
    <item  android:drawable="@drawable/a_22"  android:duration="50"/>
    <item  android:drawable="@drawable/a_23"  android:duration="50"/>
    <item  android:drawable="@drawable/a_24"  android:duration="50"/>
    <item  android:drawable="@drawable/a_25"  android:duration="50"/>
    <item  android:drawable="@drawable/a_26"  android:duration="50"/>
    <item  android:drawable="@drawable/a_27"  android:duration="50"/>
    <item  android:drawable="@drawable/a_28"  android:duration="50"/>
    <item  android:drawable="@drawable/a_29"  android:duration="50"/>
    <item  android:drawable="@drawable/a_30"  android:duration="50"/>
    <item  android:drawable="@drawable/a_31"  android:duration="50"/>
    <item  android:drawable="@drawable/a_32"  android:duration="50"/>
    <item  android:drawable="@drawable/a_33"  android:duration="50"/>
    <item  android:drawable="@drawable/a_34"  android:duration="50"/>
    <item  android:drawable="@drawable/a_35"  android:duration="50"/>
    <item  android:drawable="@drawable/a_36"  android:duration="50"/>
    <item  android:drawable="@drawable/a_37"  android:duration="50"/>
    <item  android:drawable="@drawable/a_38"  android:duration="50"/>
    <item  android:drawable="@drawable/a_39"  android:duration="50"/>
     <item  android:drawable="@drawable/a_40"  android:duration="50"/>
    <item  android:drawable="@drawable/a_41"  android:duration="50"/>
    <item  android:drawable="@drawable/a_42"  android:duration="50"/>
    <item  android:drawable="@drawable/a_43"  android:duration="50"/>
    <item  android:drawable="@drawable/a_44"  android:duration="50"/>
    <item  android:drawable="@drawable/a_45"  android:duration="50"/>
    <item  android:drawable="@drawable/a_46"  android:duration="50"/>
    <item  android:drawable="@drawable/a_47"  android:duration="50"/>
    <item  android:drawable="@drawable/a_48"  android:duration="50"/>
    <item  android:drawable="@drawable/a_49"  android:duration="50"/>
    <item  android:drawable="@drawable/a_50"  android:duration="50"/>
    <item  android:drawable="@drawable/a_51"  android:duration="50"/>
    <item  android:drawable="@drawable/a_55"  android:duration="50"/>
    <item  android:drawable="@drawable/a_53"  android:duration="50"/>
    <item  android:drawable="@drawable/a_54"  android:duration="50"/>
    <item  android:drawable="@drawable/a_55"  android:duration="50"/>
    <item  android:drawable="@drawable/a_56"  android:duration="50"/>
    <item  android:drawable="@drawable/a_57"  android:duration="50"/>
    <item  android:drawable="@drawable/a_58"  android:duration="50"/>
    <item  android:drawable="@drawable/a_59"  android:duration="50"/>  
    <item  android:drawable="@drawable/a_60"  android:duration="50"/>
    <item  android:drawable="@drawable/a_61"  android:duration="50"/>
    <item  android:drawable="@drawable/a_66"  android:duration="50"/>
    <item  android:drawable="@drawable/a_63"  android:duration="50"/>
    <item  android:drawable="@drawable/a_64"  android:duration="50"/>
    <item  android:drawable="@drawable/a_65"  android:duration="50"/>
    <item  android:drawable="@drawable/a_66"  android:duration="50"/>
    <item  android:drawable="@drawable/a_67"  android:duration="50"/>

</animation-list>

不幸的是因為圖片資源切換過多,佔用記憶體太大,在android端會報異常

Out of memory on a 19642640-byte allocation.如果圖片只有幾張那麼程式執行是正常的

Uber的android版本是沒有這個動畫效果的,不知是否因為這個原因。但是同樣的圖片在iOS是可以載入的

正確方案:

佈局 

login_layout.xml

<span style="color:#333333;"><?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/layout_login"
    android:background="@android:color/background_dark"
     >   
    <ImageView  
        android:id="@+id/login"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        />    
</FrameLayout></span><span style="color: rgb(3, 38, 204);">
</span>

MainActivity

<span style="color:#333333;">package com.example.uberstartanimation;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import java.io.InputStream;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.AnimationDrawable;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

public class MainActivity extends Activity {
//	此程式在模擬器上載入非常緩慢,如果想看到實際效果需要用真機
	private ImageView mImageView,final_imageView;
	int[] images;
	private FrameLayout layout_login;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.login_layout);
		layout_login=(FrameLayout)findViewById(R.id.layout_login);
		mImageView = (ImageView) findViewById(R.id.login);
//		android幀動畫一般是採用animation-list 如果圖片很小,那麼可以解決,但是遇到圖片過大就處理不了了
//		開發的時候發現uber這個軟體的啟動動畫是幀動畫和一個mp4視訊,但是幀動畫在iOS是行得通
//		但是在android同樣原理處理會出現oom異常,uber的android版本也沒有這個啟動動畫,
//		不知道是不是因為記憶體無法及時釋放的原因猜沒有加進去,下面的方法就完美解決了這一問題,因為缺少幾張圖片,
//		所以和uber有點不同,這沒什麼太大關係,下面是幀動畫載入過多oom問題的方案
		images = new int[68];
		images[0] = R.drawable.a_0;
		images[1] = R.drawable.a_1;
		images[2] = R.drawable.a_2;
		images[3] = R.drawable.a_3;
		images[4] = R.drawable.a_4;
		images[5] = R.drawable.a_5;
		images[6] = R.drawable.a_6;
		images[7] = R.drawable.a_7;
		images[8] = R.drawable.a_8;
		images[9] = R.drawable.a_9;
		images[10] = R.drawable.a_10;
		images[11] = R.drawable.a_11;
		images[12] = R.drawable.a_12;
		images[13] = R.drawable.a_13;
		images[14] = R.drawable.a_14;
		images[15] = R.drawable.a_15;
		images[16] = R.drawable.a_16;
		images[17] = R.drawable.a_17;
		images[18] = R.drawable.a_18;
		images[19] = R.drawable.a_19;
		images[20] = R.drawable.a_20;
		images[21] = R.drawable.a_21;
		images[22] = R.drawable.a_22;
		images[23] = R.drawable.a_23;
		images[24] = R.drawable.a_24;
		images[25] = R.drawable.a_25;
		images[26] = R.drawable.a_26;
		images[27] = R.drawable.a_27;
		images[28] = R.drawable.a_28;
		images[29] = R.drawable.a_29;
		images[30] = R.drawable.a_30;
		images[31] = R.drawable.a_31;
		images[32] = R.drawable.a_32;
		images[33] = R.drawable.a_33;
		images[34] = R.drawable.a_34;
		images[35] = R.drawable.a_35;
		images[36] = R.drawable.a_36;
		images[37] = R.drawable.a_37;
		images[38] = R.drawable.a_38;
		images[39] = R.drawable.a_39;
		images[40] = R.drawable.a_40;
		images[41] = R.drawable.a_41;
		images[42] = R.drawable.a_42;
		images[43] = R.drawable.a_43;
		images[44] = R.drawable.a_44;
		images[45] = R.drawable.a_45;
		images[46] = R.drawable.a_46;
		images[47] = R.drawable.a_47;
		images[48] = R.drawable.a_48;
		images[49] = R.drawable.a_49;
		images[50] = R.drawable.a_50;
		images[51] = R.drawable.a_51;
		images[52] = R.drawable.a_52;
		images[53] = R.drawable.a_53;
		images[54] = R.drawable.a_54;
		images[55] = R.drawable.a_55;
		images[56] = R.drawable.a_56;
		images[57] = R.drawable.a_57;
		images[58] = R.drawable.a_58;
		images[59] = R.drawable.a_59;
		images[60] = R.drawable.a_60;
		images[61] = R.drawable.a_61;
		images[62] = R.drawable.a_62;
		images[63] = R.drawable.a_63;
		images[64] = R.drawable.a_64;
		images[65] = R.drawable.a_65;
		images[66] = R.drawable.a_66;
		images[67] = R.drawable.a_67;
//		將圖片資源陣列用每次載入10張的方法載入  、
		
		new SceneAnimation(mImageView, images, 5,this,layout_login);

	}

}</span><span style="color: rgb(3, 38, 204);">
</span>

SceneAnimation

package com.example.uberstartanimation;


import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
/*
 * 一組載入10張圖片方法
 */
public class SceneAnimation {
	private ImageView mImageView;
	private int[] mFrameRess;
	private int[] mDurations;
	private int mDuration;
	private FrameLayout  login_layout;

	private int mLastFrameNo;
	private long mBreakDelay;
	private Context mContext;

	public SceneAnimation(ImageView pImageView, int[] pFrameRess,
			int[] pDurations) {
		mImageView = pImageView;
		mFrameRess = pFrameRess;
		mDurations = pDurations;
		mLastFrameNo = pFrameRess.length - 1;

		mImageView.setBackgroundResource(mFrameRess[0]);
		play(1);
	}

	public SceneAnimation(ImageView pImageView, int[] pFrameRess, int pDuration,Context mContext,FrameLayout login_layout) {
		mImageView = pImageView;
		mFrameRess = pFrameRess;
		mDuration = pDuration;
		mLastFrameNo = pFrameRess.length - 1;
		this.mContext=mContext;
		this.login_layout=login_layout;
		mImageView.setBackgroundResource(mFrameRess[0]);
		playConstant(1);
	}

	public SceneAnimation(ImageView pImageView, int[] pFrameRess,
			int pDuration, long pBreakDelay) {
		mImageView = pImageView;
		mFrameRess = pFrameRess;
		mDuration = pDuration;
		mLastFrameNo = pFrameRess.length - 1;
		mBreakDelay = pBreakDelay;

		mImageView.setBackgroundResource(mFrameRess[0]);
		playConstant(1);
	}

	private void play(final int pFrameNo) {
		mImageView.postDelayed(new Runnable() {
			public void run() {
				mImageView.setBackgroundResource(mFrameRess[pFrameNo]);
				if (pFrameNo == mLastFrameNo)
					play(0);
				else
					play(pFrameNo + 1);
			}
		}, mDurations[pFrameNo]);
	}

	private void playConstant(final int pFrameNo) {
		mImageView.postDelayed(new Runnable() {
			public void run() {
				mImageView.setBackgroundResource(mFrameRess[pFrameNo]);
				if (pFrameNo == mLastFrameNo) {
//					playConstant(0);

					ImageView finalImage=new ImageView(mContext);
					finalImage.setBackgroundResource(R.drawable.a_67);
					finalImage.setAlpha(10);
					final FullScreenVideoView mFullScreenVideoView=new FullScreenVideoView(mContext);
				    String uri = "android.resource://com.example.uberstartanimation"+"/" + R.raw.welcome_video;
			        mFullScreenVideoView.setVideoURI(Uri.parse(uri));
			        mFullScreenVideoView.start(); 
//			        視訊播放完畢的監聽事件
			        mFullScreenVideoView.setOnCompletionListener(new OnCompletionListener(){

						@Override
						public void onCompletion(MediaPlayer mp) {
//						視訊播放完進行介面的跳轉
//						Intent intent=new Intent(mContext,NextActivity.class);
//						mContext.startActivity(intent);
//						視訊播放完再重新播放即實現視訊的連續播放
							mFullScreenVideoView.start(); 
							
						}});
//			        將最後一張完整的圖片顯示出來   然後加入到佈局中,順序必須是先放視訊然後放圖片,是FrameLayout屬性			        
			        login_layout.addView(mFullScreenVideoView);
					login_layout.addView(finalImage);
				
//					System.exit(0);
					return;
				} else {
					playConstant(pFrameNo + 1);
				}
			}
		}, 5);
	}
};

FullScreenVideoView


package com.example.uberstartanimation;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.VideoView;
/*
 * author ld  使視訊全屏播放
 */
public class FullScreenVideoView extends VideoView{
	public FullScreenVideoView(Context context, AttributeSet attrs,
			int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		// TODO Auto-generated constructor stub
	}

	public FullScreenVideoView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	public FullScreenVideoView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int width = getDefaultSize(0, widthMeasureSpec);  
		  int height = getDefaultSize(0, heightMeasureSpec);  
		  setMeasuredDimension(width , height);  
	}
	
		  

}

相關推薦

仿Uber啟動完美解決動畫播放oom異常

仿照uber啟動的視屏,uber解壓以後,其實就是一個連續播放的多張圖片形成的動畫,接著就是一段Mp4 的視訊迴圈播放。 android幀動畫一般是採用animation-list 如果圖片很小,那麼可以解決,但是遇到圖片過大就處理不了了開發的時候發現uber這個軟體的啟動

Android 用surfaceview模擬動畫的效果,解決動畫OOM問題

最近做的專案,客戶臨時要求改版,我真的是最煩這個,要求跟換主頁面的背景,換上新的背景圖,要求是動態的。 效果(我隨便拿的五個圖片做的gif): 方案: 幀動畫方案:         缺點:1.好像只能imageview才能播放幀動畫                  2

Android啟動白屏問題完美解決

在開發過程中我們經常會遇到點選啟動App的時候有短暫的白屏出現,怎麼避免這種情況呢?提供倆種解決思路 1、設定透明的介面來完成 在你的style裡面加這倆行程式碼 <item name="android:windowIsTranslucent">true&l

ubuntu啟動error:unknown filesystem完美解決方案

本人安裝的是win10+ubuntu16.04,硬碟直接安裝。ea error:unknown filesystem grub rescue> 研究了半天,才解決這個問題。先說說是怎麼回事。 安裝ubuntu時,啟動是用grub2進行啟動。我的win7在C盤, Ubu

三步解決動畫圖片過多造成的OOM

主要三個步驟: 說明:我只測試了63張,蠻好用,推薦給大家 1.首先我們匯入一個我們需要的   commons-io-1.4.jar 2.新建一個 工具類MyAnimationDrawable.Java   () package com.example.frame.de

解決animation-list載入多張動畫導致OOM的問題---surfaceview用法

這次介面改版中有幾個介面的動畫實在酷炫,只有讓UI出一組png用幀動畫的形式展示了。心想著,這不簡單: <animation-list xmlns:android="http://schemas.android.com/apk/res/android" and

ios 10 開發讓我們一次性解決導航欄的所有問題

前言 今天我們來重點討論導航欄返回的問題,包括各種問題的解決方案。 系統預設導航欄的返回按鈕和返回方式 在預設情況下,導航欄返回按鈕長這個樣子 導航欄預設返回按鈕 導航欄左上角的返回按鈕,其文字預設為上一個ViewController的標題,如果上一個ViewContr

spring-boot 使用 main函數 無法啟動的問題完美 解決方案。

logs aid maven spring use ring ng- main函數 host   首先 是啟動之後 ,直接回exit code 0,網址 裏面輸入localhost:8080顯示站點未啟動。網上查 了多種 方式 ,日誌 也 打了,都沒發現問題,最後到這篇文

ubuntu18.04 完美解決網易雲音樂雙擊啟動

目錄 登錄 完成 腳本 搜索 結果 狀態 首選項 music Ubuntu的主題界面我一直很喜歡,一直想做一個雙系統,因為電腦硬盤裏的資料多,害怕失誤導致資料丟失,所以一直在用win7,但是好奇心害死貓,忍不住找了一篇雙系統的博客,結果一步一步,做了全盤。。。。。 所以現在

51Nod1625夾克爺發紅包(二進位制列舉+貪心)

正解是列舉n行的全部情況,然後針對每種情況對m列進行貪心,求最大值,最後取最大值裡的最大值。 #include<bits/stdc++.h> using namespace std; #define ll long long #define fuck(x) cout<<

51Nod1072威佐夫遊戲

有2堆石子。A B兩個人輪流拿,A先拿。每次可以從一堆中取任意個或從2堆中取相同數量的石子,但不可不取。拿到最後1顆石子的人獲勝。假設A B都非常聰明,拿石子的過程中不會出現失誤。給出2堆石子的數量,問最後誰能贏得比賽。 例如:2堆石子分別為3顆和5顆。那麼不論A怎樣拿,B

python--類例項繼承中變數的id是否變化

''' 注: 估計這麼亂的程式碼只有我自己能看。通過這段程式碼的驗證,證明了在類和例項的相對關係中, 把變數儲存為字串,數字,在各個類、例項之間變換的時候,變數的id是變化的, 把變數儲存為列表和字典的時候,id地址是不變的。id地址變與不變用於確認是否是同一份資料, 看一下這個變數是否是全域性

程式碼優化優化條件分支

 程式碼優化-之-優化條件分支                    [email pr

演算法陣列二維數字中的查詢

問題描述:每行從左到右,每列從上到下遞增的二維陣列中,判斷某個數是否存在。 1 2  8  9 2 4  9 12 4 7 10 13 6 8 11 15 7 9 12 18 思路 :從右上角開始呢?以上的矩陣,假如我們查詢的是7,從右上角開始,先比較9和7,9

小白進化記Python3 Python的資料型別

python的資料型別 回顧 命令: cp / cp -r     複製檔案/資料夾 mv       移動檔案/資料夾(改名字) cat       顯示文字檔案的內容 tar        打包並壓縮 $ tar -cz

歐美劇集觀看最佳索引 【2006924更新】

                下次更新將用上面的 urlallyesno:我在上兩個月說要做一個美劇的網站 由於最近公司的事情一直很繁忙 我沒有時間去做自己都積累了一大堆 美劇 日劇 恐怖片 沒看 兩個電腦的硬碟都塞的滿滿的 呵呵真是 天長地久有時盡,此恨綿綿無絕期。 哈哈~`` 我現在正在構思 是不是把美

Struts2啟動過程中報錯java.lang.ClassNotFoundException完美解決方案

具體報錯部分程式碼如下 嚴重: Exception starting filter struts2 java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.ng.filter.StrutsPrepare

NYOJ15括號匹配(二)

描述 給你一個字串,裡面只包含”(“,”)”,”[“,”]”四種符號,請問你需要至少新增多少個括號才能使這些括號匹配起來。 如: []是匹配的 ([])[]是匹配的 ((]是不匹配的 ([)]是不匹配的 輸入 第一行輸入一個正整數N,表示測試資料

NYOJ35表示式求值

描述 ACM隊的mdd想做一個計算器,但是,他要做的不僅僅是一計算一個A+B的計算器,他想實現隨便輸入一個表示式都能求出它的值的計算器,現在請你幫助他來實現這個計算器吧。 比如輸入:“1+2/4=”,程式就輸出1.50(結果保留兩位小數) 輸入 第一行輸

IDEA中Tomcat啟動報:java.lang.OutOfMemoryError: PermGen space異常(完美解決)

出現原因:持久代記憶體不夠 解決辦法: 第一: 在idea中新增   -server -XX:PermSize=256M -XX:MaxPermSize=512M 位置如下: 第二: 在catalina.bat中新增set JAVA_OPTS=%