技术标签: 动画 源码 mediaplayer Android animation 音乐
1. Linux 系统启动,出现Linux小企鹅画面(reboot)(Android 1.5及以上版本已经取消加载图片);
2. Android平台启动初始化,出现"A N D R I O D"文字字样画面;
3. Android平台图形系统启动,出现含闪动的ANDROID字样的动画图片(start)。
现在我们说的是第三种方式(基于模拟器):
android开机动画叫源码位于frameworks/base/cmds/bootanimation下,这个程序会将/data/local/bootanimation.zip或/system/media/bootanimation.zip里面的png图片以动画的形式播放出来。
首先,我们先来分析一下源码:
frameworks/base/cmds/bootanimation/BootAnimation.cpp
首先看一下定义的常量:
1
2
3
4
|
#define USER_BOOTANIMATION_FILE "/data/local/bootanimation.zip"
#define SYSTEM_BOOTANIMATION_FILE "/system/media/bootanimation.zip"
#define SYSTEM_ENCRYPTED_BOOTANIMATION_FILE "/system/media/bootanimation-encrypted.zip"
|
BootAnimation::readyToRun()
进入一个if判断语句
1
2
3
4
5
6
7
8
9
10
11
|
if
((encryptedAnimation &&
(access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK)
=
=
0
) &&
(mZip.
open
(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE)
=
=
NO_ERROR)) ||
((access(USER_BOOTANIMATION_FILE, R_OK)
=
=
0
) &&
(mZip.
open
(USER_BOOTANIMATION_FILE)
=
=
NO_ERROR)) ||
((access(SYSTEM_BOOTANIMATION_FILE, R_OK)
=
=
0
) &&
(mZip.
open
(SYSTEM_BOOTANIMATION_FILE)
=
=
NO_ERROR))) {
mAndroidAnimation
=
false;
}
|
BootAnimation::threadLoop()
1
2
3
4
5
|
if
(mAndroidAnimation) {
r
=
Android();
/
/
执行android字体闪动的图片
}
else
{
r
=
movie();
/
/
执行bootanimation.
zip
中提供的动画图片
}
|
1
|
|
==> BootAnimation::Android()会加载"images/android-logo-mask.png"和"images/android-logo-shine.png"
==> BootAnimation::movie()会加载bootanimation.zip中的内容
我们下载的源码里默认是没有那些个.zip动画的,所以总会跳到android字体闪动的画面
所以如果你系那个用.zip的动画那么把你做好的动画拷贝到编译好对应的目录下即可,然后执行make snod整合进img包就可以看到效果了
如果你想修改android闪动的那两张图片的话,最简单的方法是直接替换图片,如果你懂openGL的话也可以自己做酷炫的动画
那两张图片放在./frameworks/base/core/res/assets/images 目录下,一张镂空的android图,一张发光效果,动画效果就是下面那张发光的效果图不断左右移动。
我是用Photoshop直接修改的
修改完后直接替换,然后再 mmm frameworks/base , make snod 即可
以下是我修改后的效果图:
看样子还想那么回事
接下来我们给系统添加开机声音
由于动画是在BootAnimation播放的,所以我们的声音肯定也在这个类中做,照猫画虎
首先在BootAnimation.h添加方法的声明和头文件的引用
1
2
|
#include <media/AudioSystem.h>
#include <media/mediaplayer.h>
|
添加方法 void bootMusic();
然后在BootAnimation.cpp中实现这个方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
void BootAnimation::bootMusic()
{
int
index;
MediaPlayer
*
mp
=
new MediaPlayer();
if
(mp
-
>setDataSource(
"/system/etc/poweron.wav"
, NULL)
=
=
NO_ERROR) {
mp
-
>setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
mp
-
>prepare();
}
AudioSystem::getStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE, &index);
if
(index !
=
0
) {
mp
-
>seekTo(
0
);
mp
-
>start();
}
}
|
请注意这个目录setDataSource("/system/etc/poweron.wav", NULL)
其实这个目录是随便写的,你想从哪个目录读这个文件就从哪个目录读好了,但是你要把这个文件放在对应的目录下
比如,这个目录是system/etc (这个目录是android系统的目录,不是源码的目录),这个文件夹是只有读权限而没有写权限的,所有你不用试adb shell了,没用的
其实system/etc这个目录对应的是我们编译后out文件夹下的xxx,然后在system/etc,所以你把poweron.wav放到这里就行了,当然如果你这时再emulaor 也同样是看不到效果的,因为你修改完还没有编译,和上面修改图片一样,make snod一下
然后和图上一样,你就会生成新的system.img,当然你之前添加的poweron.wav也会自动被编译进去了
然后再修改bootanimation_main.cpp这个文件,因为方法也申明了,也实现了,就是还没有调用,所以调用就在这里调
1
2
3
|
/
/
play boot music
-
yp
BootAnimation
*
animation
=
new BootAnimation();
animation
-
>bootMusic();
|
修改完这写以后还需要修改Android.mk文件
因为播放声音还需要引入库
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libbinder \
libui \
libskia \
libEGL \
libGLESv1_CM \
libgui \
libmedia
请注意,libmedia是新添加的;
完事后就ok了,当然还是需要编译的
mmm frameworks/base/cmds/bootanimation/
make snod
大功告成,这样你就成功的添加了开机音乐
也许有人会问,那android系统自带的那些音乐和铃声在什么地方呢?
源码目录在framworks/base/data/sounds
至于编译完成后放到什么地方了那是Android.mk文件上配置的
不过这里叫AllAudio.mk
我们可以看到他又包含了很多mk文件,在同一目录下就可以找到,上图中就可以,我们随便打开一个看看
这下你们顿时明白了吧,这些资源编译后都去了神马地方
所以,在刚才添加poweron.wav的时候,其实可以直接把声音资源丢到framworks/base/data/sounds这个目录下
然后再mk文件中这样修改:
$(LOCAL_PATH)/poweron.wav:system/etc/poweron.wav \
不用我说,当然是执行mmm还有make snod命令了
其实还有一种办法,如果你不想这么麻烦,你可以之际把poweron.wav 文件丢到./frameworks/base/core/res/assets/sounds下,用的时候怎么用呢?
加载的时候路径是什么呢?我们看看源码
我们可以看到之前我们修改的那两张图片是怎么被加载进来的
而这个方法的两个参数是:
是不是顿时又明白了?
原来精髓所在是有个Asset可以使用,这个和上层开发中是一样的,这个文件夹中的东西是不编译的。
1
2
3
4
5
6
7
8
|
Asset
*
asset
=
assets.
open
(name, Asset::ACCESS_BUFFER);
if
(!asset)
return
NO_INIT;
SkBitmap bitmap;
SkImageDecoder::DecodeMemory(asset
-
>getBuffer(false), asset
-
>getLength(),
&bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode);
asset
-
>close();
delete asset;
|
所以按照这个方法就可以找到poweron.wav 这个文件了,然后修改下bootMusic的代码就可以了。
0x01 WebView 概述WebView 是 Android 的一个控件,用于在应用程序中展示 Web 网页Google 的官方解释为A View that displays web pages. This class is the basis upon which you can roll your own web browser or simply display some online content within your Activity. It uses the WebKit ren
点击关注公众号,实用技术文章及时了解来源:blog.csdn.net/enthan809882/article/details/104956537这里说的是spring的BeanUtils...
策略模式,即[color=red]行为类[/color]的使用,用一个类去诠释一个行为。这样当实体类需要行为时,通过它的行为类实例(行为类实例是它的数据成员)来进行委托。这种实体类和行为类的结合使用叫做组合。多用组合,少用继承,这是个很重要的技巧,这样系统会有很大的弹性。针对接口编程,不要针对实现去编程。模式设计的学习,它是对问题的通用解决办法。对于具体的类,只在它的构造函数之...
【数据分析】️走进数据分析 4️ 正则表达式.
1.11.1.NandFlash的接口1.11.1.1、Nand的型号与命名(1)Nand的型号命名都有含义,就拿K9F2G08来示例分析一下:K9F表示是三星公司的NandFlash系列。2G表示Nand的大小是2Gbit(256MB)。08表示Nand是8位的(8位就是数据线有8根)(2)Nand命名中可以看出:厂家、系列型号、容量大小、数据位数。1.11.1.2、Na
篇文章对很多没有高并发经验的程序员来说,会非常有帮助。很多程序员可能都遇到过类似的困惑:今天给大家说一自己学习高并发的方法。你可以自己写一个小的电商项目,建议最简单的单体结构的电商项目即可。从最简单的单体项目开始,然后按照以下三个阶段来学习高并发。在高并发条件下,学习对单机性能进行优化。用 Docker 容器先去运行电商项目,然后再用 jmeter、wrk 等工具去压测。在压测期间,你会发现:由于系统每个模块不同,所以性能表现就不一样。这是正常的,不同模块、不同产品对并发指标的要求本身想·是不一样的。例如,
面试时长:28分钟线程池运行原理?创建线程池参数的含义?ArrayBlockingQueue作用及实现原理?参考答案:ArrayBlockingQueue是一个阻塞式的队列,继承自AbstractBlockingQueue,间接的实现了Queue接口和Collection接口。底层以数组的形式保存数据(实际上可看作一个循环数组)。常用的操作包括 add,offer,put,remove,poll,take,peek。常用集合?TreeMap原理?CopyOnWriteArrayList原理
游戏建模师日常工作内容包括哪些?【导语】随着游戏行业的发展,游戏建模也在迅速崛起,随之火热的是游戏建模师这个岗位。因此,有许多对游戏感兴趣的朋友都想成为一名游戏建模师,成为游戏行业的一员,将爱好和工作相结合,那么游戏建模师日常工作内容包括哪些?主要表现在六个方面,分别是初模制作、高模制作、拓补低模、拆分UV、贴图的烘焙、贴图绘制,下面我们就来具体了解一下。1、初模制作角色初模的制作一般分两种,一种是在ZB中直接用Z球创建。第二种是在3DMax或者MAYA中创建大型网格,这一步主要是确认角色大型体,同时
今天连接到Oracle报错:ORA-18008: 无法找到 OUTLN 方案,前天还用得好好的,现在无论查询任何sql语句或点击列表查看都会弹出该错误提示,忙活了一阵,终于解决了,现记录一下解决方案。 问题:ORA-18008: 无法找到 OUTLN 方案。问题原因:outln用户被误删除。数据库版本:Oracle 10g( 10.2.0.3.0 )
Unity3d 使用执行DOTween动态路径动画方案一、DOTweenPath设定DOTweenPath的path然后DOPlay:尝试打Log看看设置path.wps 然后DOPlay宣告DOTweenPath尝试失败方案二、使用DOPath总结有个项目有如题的需求,主要是能给对象动态的设定路径,并执行延路径运动的动画。路径上的点是动态生成的,而且路径可能不唯一。方案一、DOTweenPath想当然的想到了DOTweenPath,路径和路径点是可以预编辑的,想着在运行中动态的设置路径就能完成。设
代码永远都是最好的诠释引入控件&lt;el-cascader :options="options" @active-item-change="getNodes" :props="props"&gt;&lt;/el-cascader&gt;动态处理获取子节点&lt;script&gt;import { getProviceList, getCityList, getAreaLi..
1、opencv保存视频1.1、读取并展示视频1.2、灰色处理1.3、调整视频大小——分辨率1.3.1、查看视频的分辨率1.3.2、调整视频的分辨率1.3、保存视频1.3.1、设置保存对象参数1.3.2、调用写入函数保存1.4、获取视频自身的宽高1.5、保存视频源码汇总2、wave保存音频2.1、读入音频2.2、ffmpeg转换格式2.3、重新读入音频2.4、获取音频参数2.5、音频切片2.6、将音频写入文件夹3、音频和无声视频合并