内容简介:通过本文,你可以 1、了解一种特别的闪屏 2、了解android版本彩蛋的实现原理 3、获得一个android各版本彩蛋的在体验App时发现了一款叫‘图凌’的app,闪屏页非常特别。从下图可以看到,是一个以桌面壁纸为背景的页面。这种闪屏效果让人眼前一亮,所以非常好奇他的实现原理。在不破解apk的情况下(破解失败,有腾讯乐固加固==),猜想了几种实现方式:
通过本文,你可以 1、了解一种特别的闪屏 2、了解android版本彩蛋的实现原理 3、获得一个android各版本彩蛋的 demo
特殊的闪屏
在体验App时发现了一款叫‘图凌’的app,闪屏页非常特别。从下图可以看到,是一个以桌面壁纸为背景的页面。
这种闪屏效果让人眼前一亮,所以非常好奇他的实现原理。在不破解apk的情况下(破解失败,有腾讯乐固加固==),猜想了几种实现方式:
1、通过Api获取壁纸,然后设置Activity的背景 2、特殊的Activity theme 复制代码
在逐个验证猜想之前,想到了一个页面的实现与‘图凌’的闪屏非常相似,就是Android的版本彩蛋(设置-关于手机-Android版本点击3下)。而这个页面是可以找到源码的。
扒源码
打开彩蛋页面,执行以下命令,可以得知Activity的名字是PlatLogoActivity。
adb shell dumpsys activity | grep "Focus"
mFocusedActivity: ActivityRecord{2829baa u0 android/com.android.internal.app.PlatLogoActivity t4844}
mFocusedStack=ActivityStack{d93bf0d stackId=1, 4 tasks} mLastFocusedStack=ActivityStack{d93bf0d stackId=1, 4 tasks}
复制代码
(或者 adb shell dumpsys activity top )
通过在线源码平台Xref,找到PlatLogoActivity,源码就不贴了,因为重点并不在 PlatLogoActivity.java ,而是在AndroidManifest,theme才是关键!也就是开始的第二个猜想。
<activity android:name="com.android.internal.app.PlatLogoActivity" android:theme="@style/Theme.Wallpaper.NoTitleBar.Fullscreen" android:configChanges="orientation|keyboardHidden" android:process=":ui"> </activity> 复制代码
试一试
通过源码基本了解了实现原理,但没有跑一下Demo是不靠谱的。 PlatLogoActivity的实现非常独立,没有太多依赖。所以copy了一下各个版本的PlatLogoActivity做了一个Demo。
Github: github.com/PortgasAce/…
探究
现在我们已经知道theme可以方便的实现‘图凌’的闪屏效果。那么代码可以实现吗?官方有开放相应的api吗?
这些问题的答案可以从theme的实现原理入手。通过google或者xref搜索theme的一些关键字,最终可以找到 PhoneWindow#generateLayout 有这样一段解析theme标签的代码:
... //省略了很多标签解析
if (a.getBoolean(R.styleable.Window_windowSwipeToDismiss, false)) {
requestFeature(FEATURE_SWIPE_TO_DISMISS);
}
if (a.getBoolean(R.styleable.Window_windowFullscreen, false)) {
setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN & (~getForcedWindowFlags()));
}
...//省略了很多标签解析
复制代码
theme的主要实现就是通过 window#requestFeature 和 window#setFlags 方法改变样式。
临摹着写了 Theme.Wallpaper.NoTitleBar.Fullscreen 的 java 实现,见 github:PlatLogoActivityNoStyle 主要代码:
requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().getDecorView().setWillNotDraw(true); getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER); 复制代码
到此为止,猜想2通过theme和java实现都是验证了。那么其他猜想是否可行呢? 答案当然是可以的啦。通过sdk提供的 WallpaperManager 可以获取桌面壁纸。
Drawable bg = WallpaperManager.getInstance(context).getDrawable(); rootView.setBackground(bg); 复制代码
以上代码就可以给Activity设置背景为桌面壁纸。
但是有一个问题。动态壁纸(live wallpapewr)时通过该方法获取的drawable不但不会动,而且是错误的图片。
其实liveWallpaper获取的正确姿势是通过 wallpaperManager#getWallpaperInfo#loadThumbnail :
private Drawable getWallpaperDrawable() {
Drawable wallpaperDrawable;
PackageManager pm = getApplicationContext().getPackageManager();
WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
if (wallpaperManager.getWallpaperInfo() != null) {
/*
* Wallpaper info is not equal to null, that is if the live wallpaper
* is set, then get the drawable image from the package for the
* live wallpaper
*/
wallpaperDrawable = wallpaperManager
.getWallpaperInfo().loadThumbnail(pm);
} else {
/*
* Else, if static wallpapers are set, then directly get the
* wallpaper image
*/
wallpaperDrawable = wallpaperManager.getDrawable();
}
return wallpaperDrawable;
}
复制代码
但是问题还是没有完全解决,背景不会动!每次调用loadThumbnail返回的图片都是一样的,因此猜想1只使用于静态壁纸。
以上。
巨人的肩膀
Andriod中Style/Theme原理以及Activity界面文件选取过程浅析: blog.csdn.net/qinjuning/a…
以上所述就是小编给大家介绍的《图凌闪屏页及Android彩蛋探究》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深入浅出WebAssembly
于航 / 电子工业出版社 / 2018-11 / 128.00元
WebAssembly是一种新的二进制格式,它可以方便地将C/C++等静态语言的代码快速地“运行”在浏览器中,这一特性为前端密集计算场景提供了无限可能。不仅如此,通过WebAssembly技术,我们还可以将基于Unity等游戏引擎开发的大型游戏快速地移植到Web端。WebAssembly技术现在已经被计划设计成W3C的标准,众多浏览器厂商已经提供了对其MVP版本标准的支持。在Google I/O ......一起来看看 《深入浅出WebAssembly》 这本书的介绍吧!