如何做淘宝cms导购网站,德阳seo优化,在线页游,免费域名注册和免费建站Android开机动画 1、BootLoader开机图片2、Kernel开机图片3、系统启动时#xff08;BootAnimation#xff09;动画3.1 bootanimation.zip位置3.2 bootanimation启动3.3 SurfaceFlinger启动bootanimation3.4 播放开机动画playAnimation3.6 开机动画退出检测3.7 简易时序图 4、… Android开机动画 1、BootLoader开机图片2、Kernel开机图片3、系统启动时BootAnimation动画3.1 bootanimation.zip位置3.2 bootanimation启动3.3 SurfaceFlinger启动bootanimation3.4 播放开机动画playAnimation3.6 开机动画退出检测3.7 简易时序图 4、bootanimation.zip文件 android12-release 推荐 Android 12 开机动画代码与流程详解 1、BootLoader开机图片 一般使用rle格式图片例如放在splash分区 adb reboot bootloader
fastboot flash splash splash.img
fastboot reboot2、Kernel开机图片 记录 kernel/drivers/video/msm/msm_fb.c 也是读出根目录下的xx.rle并显示为开机画面 3、系统启动时BootAnimation动画 使用BootAnimation程序显示开机画面如需修改开机画面不用修改代码只需按格式要求做bootanimation.zip包放在系统的/system/media目录中或/oem/media、/product/media等目录。 代码路径frameworks/base/cmds/bootanimation 3.1 bootanimation.zip位置
frameworks/base/cmds/bootanimation/BootAnimation.cpp例如bootanimation.zip
3.2 bootanimation启动
frameworks/base/cmds/bootanimation/Android.bp frameworks/base/cmds/bootanimation/bootanim.rc frameworks/base/cmds/bootanimation/bootanimation_main.cpp frameworks/base/cmds/bootanimation/BootAnimation.cpp frameworks/base/cmds/bootanimation/BootAnimationUtil.cpp SurfaceFlinger进程名bootanim bin文件/system/bin/bootanimation 对应启动入口/frameworks/base/cmds/bootanimation/bootanimation_main.cpp bootAnimationDisabled()检测系统属性debug.sf.nobootanimation、ro.boot.quiescent、ro.bootanim.quiescent.enablednoBootAnimation 是否启动开机动画。注意init进程在启动bootanimation服务是disable的不会主动将应用程序bootanimation启动起来。启动bootanimation是从surfaceFlinger这边来启动的 frameworks/base/cmds/bootanimation/bootanimation_main.cpp
int main()
{setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);bool noBootAnimation bootAnimationDisabled();ALOGI_IF(noBootAnimation, boot animation disabled);if (!noBootAnimation) {spProcessState proc(ProcessState::self());ProcessState::self()-startThreadPool();// create the boot animation object (may take up to 200ms for 2MB zip)spBootAnimation boot new BootAnimation(audioplay::createAnimationCallbacks());waitForSurfaceFlinger();boot-run(BootAnimation, PRIORITY_DISPLAY);ALOGV(Boot animation set up. Joining pool.);IPCThreadState::self()-joinThreadPool();}return 0;
}frameworks/base/cmds/bootanimation/BootAnimationUtil.cpp
bool bootAnimationDisabled() {char value[PROPERTY_VALUE_MAX];property_get(debug.sf.nobootanimation, value, 0);if (atoi(value) 0) {return true;}property_get(ro.boot.quiescent, value, 0);if (atoi(value) 0) {// Only show the bootanimation for quiescent boots if this system property is set to enabledif (!property_get_bool(ro.bootanim.quiescent.enabled, false)) {return true;}}return false;
}3.3 SurfaceFlinger启动bootanimation SurfaceFlinger启动-Android12 初始化时候 mStartPropertySetThread-Start() 在线程中设置property_set(ctl.start, bootanim)启动开机动画 /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp frameworks/native/services/surfaceflinger/StartPropertySetThread.cpp
#include cutils/properties.h
#include StartPropertySetThread.hnamespace android {StartPropertySetThread::StartPropertySetThread(bool timestampPropertyValue):Thread(false), mTimestampPropertyValue(timestampPropertyValue) {}status_t StartPropertySetThread::Start() {return run(SurfaceFlinger::StartPropertySetThread, PRIORITY_NORMAL);
}bool StartPropertySetThread::threadLoop() {// Set property service.sf.present_timestamp, consumer need check its readinessproperty_set(kTimestampProperty, mTimestampPropertyValue ? 1 : 0);// Clear BootAnimation exit flagproperty_set(service.bootanim.exit, 0);property_set(service.bootanim.progress, 0);// Start BootAnimation if not startedproperty_set(ctl.start, bootanim);// Exit immediatelyreturn false;
}} // namespace android3.4 播放开机动画playAnimation result android()android原生动画result movie()自动动画playAnimation(*mAnimation)播放动画releaseAnimation(mAnimation)释放动画资源播放动画过程initTexture(frame.map, w, h)、drawClock(animation.clockFont, part.clockPosX, part.clockPosY)、drawProgress(lastDisplayedProgress, animation.progressFont, posX, posY)、checkExit()checkExit()检测属性service.bootanim.exit退出动画 bool BootAnimation::threadLoop() {bool result;// We have no bootanimation file, so we use the stock android logo// animation.if (mZipFileName.isEmpty()) {result android();} else {result movie();}mCallbacks-shutdown();eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);eglDestroyContext(mDisplay, mContext);eglDestroySurface(mDisplay, mSurface);mFlingerSurface.clear();mFlingerSurfaceControl.clear();eglTerminate(mDisplay);eglReleaseThread();IPCThreadState::self()-stopProcess();return result;
}bool BootAnimation::movie() {if (mAnimation nullptr) {mAnimation loadAnimation(mZipFileName);}if (mAnimation nullptr)return false;// mCallbacks-init() may get called recursively,// this loop is needed to get the same resultsfor (const Animation::Part part : mAnimation-parts) {if (part.animation ! nullptr) {mCallbacks-init(part.animation-parts);}}mCallbacks-init(mAnimation-parts);bool anyPartHasClock false;for (size_t i0; i mAnimation-parts.size(); i) {if(validClock(mAnimation-parts[i])) {anyPartHasClock true;break;}}if (!anyPartHasClock) {mClockEnabled false;}// Check if npot textures are supportedmUseNpotTextures false;String8 gl_extensions;const char* exts reinterpret_castconst char*(glGetString(GL_EXTENSIONS));if (!exts) {glGetError();} else {gl_extensions.setTo(exts);if ((gl_extensions.find(GL_ARB_texture_non_power_of_two) ! -1) ||(gl_extensions.find(GL_OES_texture_npot) ! -1)) {mUseNpotTextures true;}}// Blend required to draw time on top of animation frames.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glShadeModel(GL_FLAT);glDisable(GL_DITHER);glDisable(GL_SCISSOR_TEST);glDisable(GL_BLEND);glBindTexture(GL_TEXTURE_2D, 0);glEnable(GL_TEXTURE_2D);glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);bool clockFontInitialized false;if (mClockEnabled) {clockFontInitialized (initFont(mAnimation-clockFont, CLOCK_FONT_ASSET) NO_ERROR);mClockEnabled clockFontInitialized;}initFont(mAnimation-progressFont, PROGRESS_FONT_ASSET);if (mClockEnabled !updateIsTimeAccurate()) {mTimeCheckThread new TimeCheckThread(this);mTimeCheckThread-run(BootAnimation::TimeCheckThread, PRIORITY_NORMAL);}playAnimation(*mAnimation);if (mTimeCheckThread ! nullptr) {mTimeCheckThread-requestExit();mTimeCheckThread nullptr;}if (clockFontInitialized) {glDeleteTextures(1, mAnimation-clockFont.texture.name);}releaseAnimation(mAnimation);mAnimation nullptr;return false;
}bool BootAnimation::playAnimation(const Animation animation) {const size_t pcount animation.parts.size();nsecs_t frameDuration s2ns(1) / animation.fps;SLOGD(%sAnimationShownTiming start time: % PRId64 ms, mShuttingDown ? Shutdown : Boot,elapsedRealtime());int fadedFramesCount 0;int lastDisplayedProgress 0;for (size_t i0 ; ipcount ; i) {const Animation::Part part(animation.parts[i]);const size_t fcount part.frames.size();glBindTexture(GL_TEXTURE_2D, 0);// Handle animation packageif (part.animation ! nullptr) {playAnimation(*part.animation);if (exitPending())break;continue; //to next part}// process the part not only while the count allows but also if already fadingfor (int r0 ; !part.count || rpart.count || fadedFramesCount 0 ; r) {if (shouldStopPlayingPart(part, fadedFramesCount, lastDisplayedProgress)) break;mCallbacks-playPart(i, part, r);glClearColor(part.backgroundColor[0],part.backgroundColor[1],part.backgroundColor[2],1.0f);// For the last animation, if we have progress indicator from// the system, display it.int currentProgress android::base::GetIntProperty(PROGRESS_PROP_NAME, 0);bool displayProgress animation.progressEnabled (i (pcount -1)) currentProgress ! 0;for (size_t j0 ; jfcount ; j) {if (shouldStopPlayingPart(part, fadedFramesCount, lastDisplayedProgress)) break;processDisplayEvents();const int animationX (mWidth - animation.width) / 2;const int animationY (mHeight - animation.height) / 2;const Animation::Frame frame(part.frames[j]);nsecs_t lastFrame systemTime();if (r 0) {glBindTexture(GL_TEXTURE_2D, frame.tid);} else {if (part.count ! 1) {glGenTextures(1, frame.tid);glBindTexture(GL_TEXTURE_2D, frame.tid);glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);}int w, h;initTexture(frame.map, w, h);}const int xc animationX frame.trimX;const int yc animationY frame.trimY;Region clearReg(Rect(mWidth, mHeight));clearReg.subtractSelf(Rect(xc, yc, xcframe.trimWidth, ycframe.trimHeight));if (!clearReg.isEmpty()) {Region::const_iterator head(clearReg.begin());Region::const_iterator tail(clearReg.end());glEnable(GL_SCISSOR_TEST);while (head ! tail) {const Rect r2(*head);glScissor(r2.left, mHeight - r2.bottom, r2.width(), r2.height());glClear(GL_COLOR_BUFFER_BIT);}glDisable(GL_SCISSOR_TEST);}// specify the y center as ceiling((mHeight - frame.trimHeight) / 2)// which is equivalent to mHeight - (yc frame.trimHeight)const int frameDrawY mHeight - (yc frame.trimHeight);glDrawTexiOES(xc, frameDrawY, 0, frame.trimWidth, frame.trimHeight);// if the part hasnt been stopped yet then continue fading if necessaryif (exitPending() part.hasFadingPhase()) {fadeFrame(xc, frameDrawY, frame.trimWidth, frame.trimHeight, part,fadedFramesCount);if (fadedFramesCount part.framesToFadeCount) {fadedFramesCount MAX_FADED_FRAMES_COUNT; // no more fading}}if (mClockEnabled mTimeIsAccurate validClock(part)) {drawClock(animation.clockFont, part.clockPosX, part.clockPosY);}if (displayProgress) {int newProgress android::base::GetIntProperty(PROGRESS_PROP_NAME, 0);// In case the new progress jumped suddenly, still show an// increment of 1.if (lastDisplayedProgress ! 100) {// Artificially sleep 1/10th a second to slow down the animation.usleep(100000);if (lastDisplayedProgress newProgress) {lastDisplayedProgress;}}// Put the progress percentage right below the animation.int posY animation.height / 3;int posX TEXT_CENTER_VALUE;drawProgress(lastDisplayedProgress, animation.progressFont, posX, posY);}handleViewport(frameDuration);eglSwapBuffers(mDisplay, mSurface);nsecs_t now systemTime();nsecs_t delay frameDuration - (now - lastFrame);//SLOGD(%lld, %lld, ns2ms(now - lastFrame), ns2ms(delay));lastFrame now;if (delay 0) {struct timespec spec;spec.tv_sec (now delay) / 1000000000;spec.tv_nsec (now delay) % 1000000000;int err;do {err clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, spec, nullptr);} while (err0 errno EINTR);}checkExit();}usleep(part.pause * ns2us(frameDuration));if (exitPending() !part.count mCurrentInset mTargetInset !part.hasFadingPhase()) {if (lastDisplayedProgress ! 0 lastDisplayedProgress ! 100) {android::base::SetProperty(PROGRESS_PROP_NAME, 100);continue;}break; // exit the infinite non-fading part when it has been played at least once}}}// Free textures created for looping parts now that the animation is done.for (const Animation::Part part : animation.parts) {if (part.count ! 1) {const size_t fcount part.frames.size();for (size_t j 0; j fcount; j) {const Animation::Frame frame(part.frames[j]);glDeleteTextures(1, frame.tid);}}}return true;
}3.6 开机动画退出检测 checkExit()检测属性service.bootanim.exit退出动画在playAnimation方法和android方法中都有一个checkExit方法来负责检查是否退出动画WMS中performEnableScreen()设置SystemProperties.set(service.bootanim.exit, 1) void BootAnimation::checkExit() {// Allow surface flinger to gracefully request shutdownchar value[PROPERTY_VALUE_MAX];property_get(EXIT_PROP_NAME, value, 0);int exitnow atoi(value);if (exitnow) {requestExit();}
}private void performEnableScreen() {synchronized (mGlobalLock) {ProtoLog.i(WM_DEBUG_BOOT, performEnableScreen: mDisplayEnabled%b mForceDisplayEnabled%b mShowingBootMessages%b mSystemBooted%b mOnlyCore%b. %s, mDisplayEnabled,mForceDisplayEnabled, mShowingBootMessages, mSystemBooted, mOnlyCore,new RuntimeException(here).fillInStackTrace());if (mDisplayEnabled) {return;}if (!mSystemBooted !mShowingBootMessages) {return;}if (!mShowingBootMessages !mPolicy.canDismissBootAnimation()) {return;}// Dont enable the screen until all existing windows have been drawn.if (!mForceDisplayEnabled) {if (mBootWaitForWindowsStartTime 0) {// First time we will start waiting for all windows to be drawn.mBootWaitForWindowsStartTime SystemClock.elapsedRealtime();}for (int i mRoot.getChildCount() - 1; i 0; i--) {if (mRoot.getChildAt(i).shouldWaitForSystemDecorWindowsOnBoot()) {return;}}long waitTime SystemClock.elapsedRealtime() - mBootWaitForWindowsStartTime;mBootWaitForWindowsStartTime -1;if (waitTime 10) {ProtoLog.i(WM_DEBUG_BOOT,performEnableScreen: Waited %dms for all windows to be drawn,waitTime);}}if (!mBootAnimationStopped) {Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, Stop bootanim, 0);// stop boot animation// formerly we would just kill the process, but we now ask it to exit so it// can choose where to stop the animation.SystemProperties.set(service.bootanim.exit, 1);mBootAnimationStopped true;}if (!mForceDisplayEnabled !checkBootAnimationCompleteLocked()) {ProtoLog.i(WM_DEBUG_BOOT, performEnableScreen: Waiting for anim complete);return;}try {IBinder surfaceFlinger ServiceManager.getService(SurfaceFlinger);if (surfaceFlinger ! null) {ProtoLog.i(WM_ERROR, ******* TELLING SURFACE FLINGER WE ARE BOOTED!);Parcel data Parcel.obtain();data.writeInterfaceToken(android.ui.ISurfaceComposer);surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHEDdata, null, 0);data.recycle();}} catch (RemoteException ex) {ProtoLog.e(WM_ERROR, Boot completed: SurfaceFlinger is dead!);}EventLogTags.writeWmBootAnimationDone(SystemClock.uptimeMillis());Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, Stop bootanim, 0);mDisplayEnabled true;ProtoLog.i(WM_DEBUG_SCREEN_ON, ******************** ENABLING SCREEN!);// Enable input dispatch.mInputManagerCallback.setEventDispatchingLw(mEventDispatchingEnabled);}try {mActivityManager.bootAnimationComplete();} catch (RemoteException e) {}mPolicy.enableScreenAfterBoot();// Make sure the last requested orientation has been applied.updateRotationUnchecked(false, false);
}3.7 简易时序图 4、bootanimation.zip文件
bootanimation.zip bootanimation.zip\desc.txt
1080 2400 5
p 0 5 part0bootanimation.zip\part0