Android 深色模式适配原理分析( 三 )


下面我们从源码出发来理解Force Dark的这些行为 , 以及看看系统是怎么实现Force Dark的 。
Tips:善用源码搜索网站可以方便查看系统源码 。
1. 主题
从主题设置的forceDarkAllowed入手查找 , 可以找到
frameworks/base/core/java/android/view/ViewRootImpl.java
private void updateForceDarkMode() {if (mAttachInfo.mThreadedRenderer == null) return;// 判断当前是否深色模式boolean useAutoDark = getNightMode() == Configuration.UI_MODE_NIGHT_YES;// 如果当前是深色模式if (useAutoDark) {// 获取Force Dark的系统默认值boolean forceDarkAllowedDefault =SystemProperties.getBoolean(ThreadedRenderer.DEBUG_FORCE_DARK, false);TypedArray a = mContext.obtainStyledAttributes(R.styleable.Theme);// 判断主题是否浅色主题 并且 判断主题设置的forceDarkAlloweduseAutoDark = a.getBoolean(R.styleable.Theme_isLightTheme, true)a.recycle();}// 将是否强制使用深色模式赋值给Renderer层if (mAttachInfo.mThreadedRenderer.setForceDark(useAutoDark)) {// TODO: Don't require regenerating all display lists to apply this settinginvalidateWorld(mView);}}而这个方法正式在ViewRootImpl.enableHardwareAcceleration()方法中调用的 , 因此可以得到第一个结论:强制深色模式只在硬件加速下生效 。 由于userAutoDark变量会判断当前主题是否为浅色 , 因此可以得到第二个结论:强制深色模式只在浅色主题下生效 。 直到这一步的调用链如下:
Android 深色模式适配原理分析文章插图
mAttachInfo.mThreadedRenderer为ThreadRenderer , 继承自HardwareRenderer , 指定了接下来的渲染操作由RanderThread执行 。 继续跟踪setForceDark()方法:
frameworks/base/graphics/java/android/graphics/HardwareRenderer.java
public boolean setForceDark(boolean enable) {// 如果强制深色模式变化if (mForceDark != enable) {mForceDark = enable;// 调用native层设置强制深色模式逻辑nSetForceDark(mNativeProxy, enable);return true;}return false;}private static native void nSetForceDark(long nativeProxy, boolean enabled);查找nSetForceDark()方法
frameworks/base/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
static const JNINativeMethod gMethods[] = {// ...// 在Android Runtime启动时 , 通过JNI动态注册{ "nSetForceDark", "(JZ)V", (void*)android_view_ThreadedRenderer_setForceDark },{ "preload", "()V", (void*)android_view_ThreadedRenderer_preload },};查找android_view_ThreadedRenderer_setForceDark()方法
frameworks/base/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
static void android_view_ThreadedRenderer_setForceDark(JNIEnv* env, jobject clazz,jlong proxyPtr, jboolean enable) {RenderProxy* proxy = reinterpret_cast(proxyPtr);// 调用RenderProxy的setForceDark方法proxy->setForceDark(enable);}frameworks/base/libs/hwui/renderthread/RenderProxy.cpp
void RenderProxy::setForceDark(bool enable) {// 调用CanvasContext的setForceDark方法mRenderThread.queue().post([this, enable]() { mContext->setForceDark(enable); });}frameworks/base/libs/hwui/renderthread/CanvasContext.h
// Force Dark的默认值是falsebool mUseForceDark = false;// 设置mUseForceDark标志void setForceDark(bool enable) { mUseForceDark = enable; }bool useForceDark() {return mUseForceDark;}


推荐阅读