逃离博客园,搬运一篇2015年做手游时期的旧文。

简约至上 少写代码

为什么需要闪屏

  1. 手机应用程序不应该有闪屏, Google Android 自家的 App 据说已经全面禁用闪屏。

Splash Screens Are Evil, Don't Use Them!

  1. 中国大量手机应用程序,或者说相关从业人员依旧坚持必须存在一个闪屏图片的审美。

为什么需要原生实现

  1. UnrealEngine3 需要
    UE3 初始化和场景切换时,渲染线程暂停,因此需要使用原生方案显示图片或视频来过渡等待。
  2. cocos2d-x 需要
    cocos2d-x 论坛相关讨论帖
  3. Unity3D
    大概类似,未考证。

为什么不应该使用 Splash Activity

“你搜到的都是错的”
网上搜索 Android 闪屏实现方案,99%的结果都是介绍如何使用一个简单的 Activity 实现,再过渡切换到真正的 GameActivity 。这种方案仅限教学,实际应用有很多弊端。

  1. 这种方案要求在 AndroidManifest.xml 中配置的 LaunchActivity 必须是 SplashActivity
    当需要实现带参数 Intent 启动时,SplashActivity 需要正确地传递参数(Intent)给 GameActivity。繁琐。
  2. 游戏使用 NDK 开发,OpenGL, UI View, thread 需要跟 GameActivity's SurfaceView 绑定。
    SplashActivity 显示期间,GameActivity 无法被加载,因此也无法并行加载游戏引擎相关实例。导致闪屏过后,GameActivity 仍需一个加载界面用于过渡等待 GameEngine 的启动耗时。
  3. 游戏需要接入各种 SDK。很多 SDK 要求在 GameActivity 的生命周期插入诸多 hook 事件代码。
    例如 onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy() 等等,这些是常用 hook 位置。
    SplashActivity 方案使相关逻辑实现更复杂。

一种适合游戏的简单闪屏实现方案

  1. 使用一个全屏 Dialog
    Android Dialog 拥有独立的 Window ,与 GameView 无耦合。
  2. 屏蔽 User Input Event
    Dialog 默认接收所有User Input Event ,不需要传递给 GameView,因此与游戏逻辑无耦合。
  3. 实现动画
    可以很方便的使用各种原生 Android Animation ,实现可用的过渡动画呈现。
  4. 动画结束后自动消失
    Dialog 可以自我管理生命周期,再次与游戏无耦合。
  5. 并行加载游戏实例
    GameSurfaceView and GameEngine 可以在 Dialog 显示期间,后台并行加载,无耦合,且真正达到异步和节省时间的目标。

代码示例

  1. 创建全屏 Dialog
public class NSSplashDialog extends Dialog {private PercentFrameLayout mLayout = null;private ImageView mImageView = null;public NSSplashDialog(Context context) {super(context, android.R.style.Theme_NoTitleBar_Fullscreen);setContentView(R.layout.splash);mLayout = (PercentFrameLayout)findViewById(R.id.layout_splash);mImageView = (ImageView)this.findViewById(R.id.iv_splash);}
}
复制代码

2 . 屏蔽 User Input Event

setCanceledOnTouchOutside(false);
setCancelable(false);
复制代码

3 . 实现动画

private AlphaAnimation mAnimation = null;
private int mBitmapIndex = 0;mAnimation = new AlphaAnimation(0.0f, 1.0f); //fade in, fade out
mAnimation.setDuration(2000);//2 seconds
mAnimation.setRepeatCount(3); //show 4 images
mAnimation.setAnimationListener(new Animation.AnimationListener(){@Overridepublic void onAnimationStart(Animation animation) {mBitmapIndex = 0;mLayout.setBackgroundColor(Color.WHITE);mImageView.setImageDrawable(BitmapUtil.loadDrawable(getContext(), R.drawable.splash0));}@Overridepublic void onAnimationEnd(Animation animation) {mBitmapIndex = 0;kick(false);}@Overridepublic void onAnimationRepeat(Animation animation) {mBitmapIndex++;switch(mBitmapIndex) {case 1:mLayout.setBackgroundColor(Color.WHITE);mImageView.setImageDrawable(BitmapUtil.loadDrawable(getContext(), R.drawable.splash1));break;case 2:mLayout.setBackgroundColor(Color.BLACK);mImageView.setImageDrawable(BitmapUtil.loadDrawable(getContext(), R.drawable.splash2));break;case 3:mLayout.setBackgroundColor(Color.BLACK);mImageView.setImageDrawable(BitmapUtil.loadDrawable(getContext(), R.drawable.splash3));break;default:break;}}
});mImageView.setAnimation(mAnimation);
复制代码

4 . 动画结束后自动消失

onAnimationEnd()中调用kick(false),即关闭自己。

实测发现部分系统有bug:onAnimationEnd() 和 cancel() 可能会死循环,因此添加保护逻辑判断 hasEnded()

public void kick(boolean show) {if(show) {show();mAnimation.start();} else {if(!mAnimation.hasEnded()) {mAnimation.cancel();}dismiss();}
}
复制代码

5 . 闪屏与游戏并行加载

GameActivity 生命周期中, 在 onCreate() 创建 SplashDialog 实例,在 onDestroy() 清除 SplashDialog 实例。

    //CreatemSplashDialog = new NSSplashDialog(this);mSplashDialog.kick(true);//Destroyif(mSplashDialog != null && mSplashDialog.isShowing()) {mSplashDialog.kick(false);}
复制代码

Loading View

闪屏说完了,最后提一下 Loading View

上面说到 UE3 在场景切换时,需要使用平台原生界面做过渡展示。根据业务需求不同,可能有时候不便复用 SplashDialog,那可以使用一个独立 layout View 实现。

转载于:https://juejin.im/post/5cee10de51882512c54cad17

Android 手游闪屏极简方案相关推荐

  1. 侏罗纪世界手游显示无法登陆到服务器,侏罗纪世界手游闪退怎么办 游戏闪退解决方法...

    当你玩游戏玩得正高兴的时候,游戏突然出现闪退怎么办?侏罗纪世界手游根据同名电影改编,是一款模拟经营&策略养成手游.我们来看看如何解决游戏闪退的问题吧. 一.手机系统问题 对于安卓系统现在主流的 ...

  2. Android手游SDK那点事(四)聚合打包

    更新: 聚合SDK 我们的SDK其实也可以称为聚合SDK,所谓聚合,就是CP游戏方接入聚合SDK,然后通过打包工具将游戏分发到更多渠道上,我们的SDK也有这个能力,相对渠道少一点 分发渠道包 以下操作 ...

  3. 浅析android手游lua脚本的加密与解密(番外篇之反编译的对抗)

    前言   去年在看雪论坛写了一篇<浅析android手游lua脚本的加密与解密>的精华文章,今年写一篇番外篇,将一些lua反编译对抗的内容整合一起,并以3个实例作为说明(包括2018腾讯游 ...

  4. Android手游《》斗地主完整的源代码(支持单机和网络对战)

    Android手游<斗地主>完整的源代码(支持单机和网络对战)下载.一个很不错的源代码. 斗地主掌游是一个独特的国内社会斗地主棋牌游戏,之后玩家可以下载网上斗地主和全世界.掌游斗地主特点: ...

  5. 浅析android手游lua脚本的加密与解密

    2018.05.02更新 这段时间在翻备份的硬盘,突然发现了以前的分析项目和代码,从里面提取了之前附件的内容,现在上传给大家,真是柳暗花明又一村啊.附件包括201703版本的梦幻手游里面提取的so文件 ...

  6. 安卓修改大师揭秘Android手游破解全过程

    由于安卓修改大师的零门槛学习成本,让安卓应用程序的破解和二次开发变得相当简单,也正因如此,手机APP遭受破解和盗版问题长期存在,且愈演愈烈.尤其是手游行业,如刀塔传奇.植物大战僵尸.2048等知名游戏 ...

  7. 关于android手游Sdk开发的专题(一)

    随着手游行业的蓬勃发展,以及各大IP加入,对于Android手游插件sdk的开发也多了起来. 下面我将给大家分享手游插件的开发细节 1.sdk开发与传统的app开发的不同点 首先做为sdk由于要兼容e ...

  8. Android手游SDK那点事(二)SDK项目结构设计(初版,废弃)

    项目构建 上一个完整架构图 以KSDK为名称模拟项目构建 项目建议: 1.这里游戏sdk不使用mvp或者mmvm的方式,其实这两种模式开发者在开发应用的时候不要盲目的使用,根据自己项目业务情况选择一个 ...

  9. Android手游SDK那点事(一)简述

    常见名词 CP:游戏厂商,就是开发游戏的,一般情况下CP常常指提供游戏的一方,不一定是研发,只要接入我们SDK,提供给我们游戏,你就是CP. 发行:代理游戏产品,进行渠道的发行. SDK:这里指游戏开 ...

最新文章

  1. openssl 编译参数选项
  2. leetcode算法题--求1+2+…+n
  3. Visual formatting model(图)
  4. python mysql library popular_python之mysql入门详解(四)
  5. 【ICCV2019】完整论文列表
  6. 蓝桥杯 ADV-109 算法提高 征税程序
  7. 领域自适应论文(六十八):Implicit Class-Conditioned Domain Alignment for Unsupervised Domain Adaptation论文原理
  8. 计算某一天是星期几(C语言,可运行)
  9. 当你痛苦时,想想别人更深重的痛苦吧!
  10. 【C语言学习】C语言入门
  11. 21届秋招ATL宁德新能源一面面经[数据分析工程师]
  12. 微信头像跨域问题解决
  13. 如何把优盘图标换成自己喜欢的图片
  14. 玩客云刷甜糖(2022-7-26亲测)
  15. HTML中图片和文字的对齐方式
  16. STM32F4+DP83848以太网通信指南系列(一):知识储备
  17. 【计算机网络实验】动态路由协议——华为eNSP(详细实验报告+代码)
  18. 小米4A千兆版刷机telnet失败解决办法
  19. 火车票报销凭证打印跑政通
  20. 在线ps html源码,PSD to HTML5 - 专业前端切图(PSDoHTML.com)

热门文章

  1. java中如何调用属性_java – 如何从属性文件导入值并在注释中使用它?
  2. leetcode实践:通过链表存储两数之和
  3. 单向链表的简单Java实现-sunziren
  4. cuDNN编写卷积实例
  5. 07-异常处理——动手动脑
  6. struts 标签s:ierator的简单使用说明
  7. 小鑫与斐波那契(一)
  8. java中的泛型(E)
  9. ProtoBuf协议详解
  10. python 文本框位置_「每日一练」Python文本框的显示和插入