仿Uber启动---完美解决帧动画播放oom异常

来源:互联网 发布:excel数据透视表视频 编辑:程序博客网 时间:2024/05/14 05:39

仿照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;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.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);elseplay(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(){@Overridepublic 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}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int width = getDefaultSize(0, widthMeasureSpec);    int height = getDefaultSize(0, heightMeasureSpec);    setMeasuredDimension(width , height);  }  }
源代码下载:点击打开链接
0 0