验证环境

aosp 12.0 源码,分支 android-12.0.0_r3 可以参考之前写的 android12.0(S) Pixel 3XL (QCOM 845) 编译刷机

AndroidStudio 版本 Android Studio Arctic Fox | 2020.3.1 Patch 4

gradle 版本 gradle-7.0.2-bin.zip gradle:7.0.4

二手 Pixel 3 XL一台可直接烧写上面编译的 rom(没有真机也可用模拟器)

源码链接

完整的 Launcher3 可直接运行调试源码已经上传 GitHub

分析流程

aosp 中 Launcher3 源码路径为 packages/apps/Launcher3

整体源码结构如下

乍一看还是有些复杂的,万变不离其宗,我们找准切入点即可。源码中的app编译规则都在根目录 Android.bp 或者 Android.mk中,

可以看到 Launcher3 中两个都有,打开 bp 文件查看并未找到编译 apk 的规则,那必定是在 mk 中。

mk 中信息量有点大,定义了编译3个 apk

LOCAL_PACKAGE_NAME := Launcher3Go

LOCAL_PACKAGE_NAME := Launcher3QuickStep

LOCAL_PACKAGE_NAME := Launcher3QuickStepGo

我们首先需要确认当前设备中使用哪一个 apk,可以通过指令 adb shell pm path com.android.launcher3

通过指令确认目前设备中运行 Launcher3 对应apk为 Launcher3QuickStep.apk

再回到 mk 中对应编译规则为

packages\apps\Launcher3\Android.mk

#
# Build rule for Quickstep app.
#
include $(CLEAR_VARS)
LOCAL_USE_AAPT2 := true
LOCAL_MODULE_TAGS := optional
# 依赖静态android类库 Launcher3QuickStepLib  可以理解为AS中 module
LOCAL_STATIC_ANDROID_LIBRARIES := Launcher3QuickStepLib
LOCAL_PROGUARD_ENABLED := disabledifneq (,$(wildcard frameworks/base))LOCAL_PRIVATE_PLATFORM_APIS := true
elseLOCAL_SDK_VERSION := system_currentLOCAL_MIN_SDK_VERSION := 26
endif
# 指定编译产物 apk 名称
LOCAL_PACKAGE_NAME := Launcher3QuickStep
# 编译产物路径是否在 priv-app 下
LOCAL_PRIVILEGED_MODULE :=
# 编译产物路径是否在 system_ext 下
LOCAL_SYSTEM_EXT_MODULE := true
# 覆盖编译,编译 Launcher3QuickStep 就会忽略 Home Launcher2 Launcher3,不生成对应 apk
LOCAL_OVERRIDES_PACKAGES := Home Launcher2 Launcher3
# 依赖 frameworks/base/data/etc/com.android.launcher3.xml
LOCAL_REQUIRED_MODULES := privapp_whitelist_com.android.launcher3
# 资源文件源码
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/quickstep/res#网上没找到准确的解释,根据编译得到 apk 中的 xml 查看后猜测最终是将这里定义的两个 xml 和下面 quickstep/AndroidManifest.xml 合并
LOCAL_FULL_LIBS_MANIFEST_FILES := \$(LOCAL_PATH)/quickstep/AndroidManifest-launcher.xml \$(LOCAL_PATH)/AndroidManifest-common.xmlLOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml
LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.launcher3.*LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
LOCAL_LICENSE_CONDITIONS := notice
LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
include $(BUILD_PACKAGE)

小结一下

Launcher3QuickStep.apk||需要android类库 Launcher3QuickStepLib

看完对应 mk 发现仅仅只依赖 Launcher3QuickStepLib 接下来看看这家伙是何方神圣,同样也定义在 Android.mk

packages\apps\Launcher3\Android.mk

#
# Build rule for Quickstep library.
#
include $(CLEAR_VARS)
LOCAL_USE_AAPT2 := true
LOCAL_AAPT2_ONLY := true
LOCAL_MODULE_TAGS := optional
# 依赖静态java库,最终打包到 apk 中  可以理解为AS中 libs 下 jar
LOCAL_STATIC_JAVA_LIBRARIES := \SystemUI-statsd \SystemUISharedLib
ifneq (,$(wildcard frameworks/base))LOCAL_PRIVATE_PLATFORM_APIS := true
elseLOCAL_SDK_VERSION := system_currentLOCAL_MIN_SDK_VERSION := 26
endif
LOCAL_MODULE := Launcher3QuickStepLib
LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
LOCAL_LICENSE_CONDITIONS := notice
LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
LOCAL_PRIVILEGED_MODULE := true
# 依赖静态android类库 Launcher3CommonDepsLib
LOCAL_STATIC_ANDROID_LIBRARIES := Launcher3CommonDepsLib# java 源代码
LOCAL_SRC_FILES := \$(call all-java-files-under, src) \$(call all-java-files-under, quickstep/src) \$(call all-java-files-under, src_shortcuts_overrides)# 资源文件源码
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/quickstep/res
LOCAL_PROGUARD_ENABLED := disabledLOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml
include $(BUILD_STATIC_JAVA_LIBRARY)

小结一下

Launcher3QuickStep.apk||android类库-Launcher3QuickStepLib||静态java库-SystemUI-statsd|静态java库-SystemUISharedLib|android类库-Launcher3CommonDepsLib

好嘛,开始套娃了。接下来我们又要看 Launcher3CommonDepsLib 这家伙藏在哪里,在 android.bp 中被发现

packages\apps\Launcher3\Android.bp

//
// Build rule for Launcher3 dependencies lib.
//
android_library {name: "Launcher3CommonDepsLib",//对应Java源码srcs: ["src_build_config/**/*.java"],//又依赖 Launcher3ResLibstatic_libs: ["Launcher3ResLib"],sdk_version: "current",min_sdk_version: min_launcher3_sdk_version,//对应 xml 源码manifest: "AndroidManifest-common.xml",lint: {baseline_filename: "lint-baseline-common-deps-lib.xml",},
}// Library with all the dependencies for building Launcher3
android_library {name: "Launcher3ResLib",//没有java源码srcs: [ ],//对应资源文件源码resource_dirs: ["res"],//依赖静态java库static_libs: ["LauncherPluginLib","launcher_quickstep_log_protos_lite","androidx-constraintlayout_constraintlayout","androidx.recyclerview_recyclerview","androidx.dynamicanimation_dynamicanimation","androidx.fragment_fragment","androidx.preference_preference","androidx.slice_slice-view","androidx.cardview_cardview","iconloader_base",],manifest: "AndroidManifest-common.xml",sdk_version: "current",min_sdk_version: min_launcher3_sdk_version,lint: {baseline_filename: "lint-baseline-res-lib.xml",},
}java_library {name: "LauncherPluginLib",//依赖静态java库static_libs: ["PluginCoreLib"],srcs: ["src_plugins/**/*.java"],sdk_version: "current",min_sdk_version: min_launcher3_sdk_version,
}java_library_static {name: "launcher_quickstep_log_protos_lite",srcs: ["quickstep/protos_overrides/*.proto",],sdk_version: "current",proto: {type: "lite",local_include_dirs:["quickstep/protos_overrides",],},//依赖静态java库static_libs: ["libprotobuf-java-lite","launcher_log_protos_lite"],
}

卧底马,终于套娃结束了,来看下

最终结构

Launcher3QuickStep.apk||android类库-Launcher3QuickStepLib||静态java库-SystemUI-statsd|静态java库-SystemUISharedLib|android类库-Launcher3CommonDepsLib||android类库-Launcher3ResLib||静态java库-LauncherPluginLib||静态java库-PluginCoreLib                                                                     |静态java库-launcher_quickstep_log_protos_lite||静态java库-libprotobuf-java-lite|静态java库-launcher_log_protos_lite||静态java库-libprotobuf-java-lite|android类库-androidx-constraintlayout_constraintlayout|android类库-androidx.recyclerview_recyclerview|android类库-androidx.dynamicanimation_dynamicanimation|android类库-androidx.fragment_fragment|android类库-androidx.preference_preference|android类库-androidx.slice_slice-view|android类库-androidx.cardview_cardview|静态java库-iconloader_base

静态java库从aosp12 源码编译 out 目录下搜索得到,一共 9 个 jar 文件

\192.168.123.100/share/Pixel12/alps/out/soong$ find ./ -name xxxx.jar

-rw-rw-r-- 1 cczheng cczheng 13164863 10月 3 15:33 framework.jar
-rw-rw-r-- 1 cczheng cczheng 126323 1月 26 09:41 iconloader_base.jar
-rw-rw-r-- 1 cczheng cczheng 190376 10月 3 15:53 launcher_log_protos_lite.jar
-rw-rw-r-- 1 cczheng cczheng 9223 10月 3 14:19 LauncherPluginLib.jar
-rw-rw-r-- 1 cczheng cczheng 18387 10月 3 14:21 launcher_quickstep_log_protos_lite.jar
-rw-rw-r-- 1 cczheng cczheng 478345 10月 3 15:53 libprotobuf-java-lite.jar
-rw-rw-r-- 1 cczheng cczheng 5057 10月 3 16:01 PluginCoreLib.jar
-rw-rw-r-- 1 cczheng cczheng 238871 10月 3 13:32 SystemUISharedLib.jar
-rw-rw-r-- 1 cczheng cczheng 6587 10月 3 13:29 SystemUI-statsd.jar

android类库 androidx 相关直接在 gradle 中引入即可, Launcher 相关的需要我们新建 module,一共 3 个 module

移植过程

1、在AS中新建 project Launcher3,选择 empty activity

工程创建成功后,删除 androidTest 和 test 文件夹 和 res 文件夹 和 MainActivity.java

导入源码

导入资源文件

上面说到的三个 AndroidManifest.xml

quickstep/AndroidManifest-launcher.xml

AndroidManifest-common.xml

quickstep/AndroidManifest.xml

合并得到最终 AndroidManifest.xml,就将 application 中内容和外面权限合并

2、新建 module Launcher3QuickStepLib

module Launcher3QuickStepLib 创建成功后,删除 androidTest 和 test 文件夹

修改 app/build.gradle,增加依赖 Launcher3QuickStepLib

implementation project(path: ‘:Launcher3QuickStepLib’)

导入源码

将 src 、quickstep/src、src_shortcuts_overrides copy 到 Launcher3QuickStepLib/src/main/java 目录下

导入资源文件

将 quickstep/res 中文件 copy 到 app/src/main 目录下

导入 libs

SystemUI-statsd.jar 和 SystemUISharedLib.jar

修改 Launcher3QuickStepLib/build.gradle,增加依赖

implementation files(‘libs\SystemUI-statsd.jar’)
implementation files(‘libs\SystemUISharedLib.jar’)
implementation project(path: ‘:Launcher3CommonDepsLib’)

3、新建 module Launcher3CommonDepsLib

module Launcher3CommonDepsLib 创建成功后,删除 androidTest 和 test 文件夹,并将 AndroidManifest.xml 中

package 修改为 com.android.launcher3.common 不然和 app 中报名冲突,编译会报错

导入源码

将 src_build_config copy 到 Launcher3CommonDepsLib/src/main/java 目录下

导入资源文件

4、新建 module Launcher3ResLib

module Launcher3ResLib 创建成功后,删除 androidTest 和 test 文件夹,并将 AndroidManifest.xml 中

package 修改为 com.android.launcher3.res 不然和 app 中报名冲突,编译会报错

修改 Launcher3CommonDepsLib/build.gradle,增加依赖 Launcher3ResLib

implementation project(path: ‘:Launcher3ResLib’)

导入源码

导入资源文件

将 res copy 到 Launcher3ResLib/src/main/ 目录下

导入 libs

LauncherPluginLib.jar

PluginCoreLib.jar

launcher_quickstep_log_protos_lite.jar

libprotobuf-java-lite.jar

launcher_log_protos_lite.jar

iconloader_base.jar

修改 Launcher3ResLib/build.gradle,增加依赖

    api files('libs\\iconloader_base.jar')api files('libs\\launcher_log_protos_lite.jar')api files('libs\\launcher_quickstep_log_protos_lite.jar')api files('libs\\LauncherPluginLib.jar')api files('libs\\libprotobuf-java-lite.jar')api files('libs\\PluginCoreLib.jar')

此处用 api 是因为套娃原因,Launcher3ResLib 中没有 src,都是给引用它的 module 提供便利

再处理 Androidx 相关库依赖,在阿里仓库中搜索对应库版本号

 api 'androidx.constraintlayout:constraintlayout:2.1.0'api 'androidx.recyclerview:recyclerview:1.2.1'api 'androidx.dynamicanimation:dynamicanimation:1.1.0-alpha03'api 'androidx.fragment:fragment:1.4.1'api 'androidx.preference:preference:1.2.0-alpha01'
//    api 'androidx.slice:slice-view:1.1.0-alpha02'api 'androidx.slice:slice-core:1.1.0-alpha02'api 'androidx.slice:slice-builders:1.1.0-alpha02'api 'androidx.cardview:cardview:1.0.0-rc02'

编译排错

做完上面的步骤后,代码都已经准备完成,接下来就是 build 和处理错误了

1、程序包 com.android.launcher3.icons 找不到

解决办法 Launcher3CommonDepsLib build.gradle 中改为 api project(path: ‘:Launcher3ResLib’)

2、程序包 android.os 找不到

解决办法

将 aosp 编译后 framework.jar 引入 AS 中,解决编译时报错。

在这地方卡了好长时间,一开始按照这个试了试

https://blog.csdn.net/u013885959/article/details/84325173

因为我的 gradle 版本太高,按照网上的资料无法使用 XmlParser 和 Node,一开始我降低了 gradle

并确保sdk使用顺序已经是 framework.jar 优于默认版本,怎么试都还是不行,最后找到了解决办法。

将 framework.jar copy 到 app/libs 下,app/build.gradle 中配置

compileOnly files(‘libs\framework.jar’)

compileOnly 很关键,只是编译使用,并不打包到 apk 中,最终运行还是使用设备上的

修改 Launcher3/build.gradle 中增加配置

  allprojects {gradle.projectsEvaluated {tasks.withType(JavaCompile) {options.compilerArgs.add("-Xbootclasspath/p:${project.rootDir}/app/libs/framework.jar")}}}

3、类 ContainerCase 找不到符号 仅从类和接口静态导入

根据报错其实可以跳转到 launcher_quickstep_log_protos_lite.jar 中,

报错提示在 module Launcher3QuickStepLib 中找不到

解决办法

将 launcher_quickstep_log_protos_lite.jar 从 module Launcher3ResLib 移动到 Launcher3QuickStepLib 中

并修改 Launcher3QuickStepLib/build.gradle 中配置

compileOnly files(‘libs\launcher_quickstep_log_protos_lite.jar’)

4、类 BuildConfig 找不到 变量 APPLICATION_ID

这是由于 Google 早已在 Android Studio 3.5 之后做出了变更:

BuildConfig: Deprecate APPLICATION_ID in libraries.
It is at best misleading, so it is marked as deprecated and replaced by LIBRARY_PACKAGE_NAME.

在 library 中已经把 BuildConfig.APPLICATION_ID 字段废弃掉,因为很容易造成误导,因此使用 BuildConfig.LIBRARY_PACKAGE_NAME 代替

解决办法

将报错 module 中 APPLICATION_ID 全替换为 LIBRARY_PACKAGE_NAME

5、attr/disabledIconAlpha (aka com.android.launcher3:attr/disabledIconAlpha) not found

解决办法

全局搜索 disabledIconAlpha 属性,先将其注释。一共 5 个地方

6、attr/loadingIconColor (aka com.android.launcher3:attr/loadingIconColor) not found.

解决办法

全局搜索 loadingIconColor 属性,先将其注释。一共 2 个地方

这两问题先暂时这样处理,后面会有解决方法

7、com.android.launcher3.BuildConfig is defined multiple times

在 Launcher3QuickStepLib 和 Launcher3CommonDepsLib 中都存在 BuildConfig

解决办法

去掉 Launcher3CommonDepsLib 中 BuildConfig.java,因为看起来没用

至此已经可以成功 build 出 apk 了

运行排错

接下来就把 apk 运行起来看看是否正常

1、INSTALL_FAILED_VERSION_DOWNGRADE

adb install -r E:\android\AS_WorkSpace\Launcher3\app\build\outputs\apk\debug\app-debug.apk
Performing Streamed Install
adb: failed to install E:\android\AS_WorkSpace\Launcher3\app\build\outputs\apk\debug\app-debug.apk: Failure [INSTALL_FAILED_VERSION_DOWNGRADE: Package Verification Result]

解决办法

修改 app/build.gradle 中 versionCode 32 versionName “12.1” ,先查看设备上原始 apk 版本,重新运行

如果遇到签名不一致的问题,先将设备里的 Launcher3 apk 给 rm 掉

2、 Error: -127 android.permission-group.SYSTEM_TOOLS

Installation failed due to: ‘Failed to commit install session 813937487 with command cmd package install-commit 813937487. Error: -127: Package com.android.launcher3 attempting to declare permission com.android.launcher3.permission.WRITE_SETTINGS in group android.permission-group.SYSTEM_TOOLS owned by package com.android.launcher3 with incompatible certificate’

解决办法

在 app/src/main/AndroidManifest.xml 中增加如下语句,重新运行

3、Could not identify launch activity: Default Activity not found Error while Launching activity

解决办法

为了测试,在 app/src/main/AndroidManifest.xml 中,增加

<intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /><category android:name="android.intent.category.HOME" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.MONKEY"/><category android:name="android.intent.category.LAUNCHER_APP" />
</intent-filter>

4、Permission denial: reading from settings requires:android.permission.READ_DEVICE_CONFIG

虽然声明了权限

但普通 app 还是无法获取这个权限的

解决办法

给 apk 系统签名后再运行

5、android.content.res.Resources$NotFoundException: Resource ID #0x0

根据错误堆栈信息找到问题出在 iconloader_base.jar 中,里面包含一个 R.class,所有的资源 id 全都

为 0,这就是为什么出现上面的崩溃 Resource ID #0x0

解决办法

将 iconloader_base.jar 作为 module 引入,在 aosp 源码中找到 iconloader_base 代码位置

frameworks/libs/systemui/iconloaderlib/

新建 module Launcher3IconLoadeBase

和上面一样操作,删除无用文件夹,然后导入java源码和资源文件

还记得上面编译错误 5 和 6 么,attr/disabledIconAlpha 和 attr/loadingIconColor 找不到,

巧了这两兄弟就在 iconloaderlib 源码中,这下就可以解决上面的问题。

修改 Launcher3ResLib/build.gradle 中引入依赖

// api files(‘libs\iconloader_base.jar’)
api project(path: ‘:Launcher3IconLoadeBase’)

再次重新运行

成功啦

运行结果图

各个 build.gradle 详细配置

\AS_WorkSpace\Launcher3\build.gradle

buildscript {repositories {google()mavenCentral()}dependencies {classpath "com.android.tools.build:gradle:7.0.4"}allprojects {gradle.projectsEvaluated {tasks.withType(JavaCompile) {options.compilerArgs.add("-Xbootclasspath/p:${project.rootDir}/app/libs/framework.jar")}}}
}

AS_WorkSpace\Launcher3\app\build.gradle

dependencies {implementation project(path: ':Launcher3QuickStepLib')compileOnly files('libs\\framework.jar')implementation 'androidx.appcompat:appcompat:1.2.0'implementation 'com.google.android.material:material:1.3.0'implementation 'androidx.constraintlayout:constraintlayout:2.0.4'testImplementation 'junit:junit:4.+'androidTestImplementation 'androidx.test.ext:junit:1.1.2'androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

AS_WorkSpace\Launcher3\Launcher3QuickStepLib\build.gradle

dependencies {implementation files('libs\\SystemUI-statsd.jar')implementation files('libs\\SystemUISharedLib.jar')compileOnly files('libs\\launcher_quickstep_log_protos_lite.jar')api project(path: ':Launcher3CommonDepsLib')implementation 'androidx.appcompat:appcompat:1.2.0'implementation 'com.google.android.material:material:1.3.0'testImplementation 'junit:junit:4.+'androidTestImplementation 'androidx.test.ext:junit:1.1.2'androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

AS_WorkSpace\Launcher3\Launcher3CommonDepsLib\build.gradle

dependencies {api project(path: ':Launcher3ResLib')/* implementation 'androidx.appcompat:appcompat:1.2.0'implementation 'com.google.android.material:material:1.3.0'testImplementation 'junit:junit:4.+'androidTestImplementation 'androidx.test.ext:junit:1.1.2'androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'*/
}

AS_WorkSpace\Launcher3\Launcher3ResLib\build.gradle

dependencies {//    api files('libs\\iconloader_base.jar')api project(path: ':Launcher3IconLoadeBase')api files('libs\\launcher_log_protos_lite.jar')
//    api files('libs\\launcher_quickstep_log_protos_lite.jar')api files('libs\\LauncherPluginLib.jar')api files('libs\\libprotobuf-java-lite.jar')api files('libs\\PluginCoreLib.jar')api 'androidx.constraintlayout:constraintlayout:2.1.0'api 'androidx.recyclerview:recyclerview:1.2.1'api 'androidx.dynamicanimation:dynamicanimation:1.1.0-alpha03'api 'androidx.fragment:fragment:1.4.1'api 'androidx.preference:preference:1.2.0-alpha01'
//    api 'androidx.slice:slice-view:1.1.0-alpha02'api 'androidx.slice:slice-core:1.1.0-alpha02'api 'androidx.slice:slice-builders:1.1.0-alpha02'api 'androidx.cardview:cardview:1.0.0-rc02'/*implementation 'androidx.appcompat:appcompat:1.2.0'implementation 'com.google.android.material:material:1.3.0'testImplementation 'junit:junit:4.+'androidTestImplementation 'androidx.test.ext:junit:1.1.2'androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'*/
}

AS_WorkSpace\Launcher3\Launcher3IconLoadeBase\build.gradle

dependencies {implementation 'androidx.appcompat:appcompat:1.2.0'implementation 'com.google.android.material:material:1.3.0'testImplementation 'junit:junit:4.+'androidTestImplementation 'androidx.test.ext:junit:1.1.2'androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

android12.0(S) Launcher3 导入 AndroidStudio 调试编译相关推荐

  1. android12.0(S) Pixel 3XL (QCOM 845) 编译刷机

    androidS 发布已经有一段时间了,作为一名搞机人,咱也不能落后,今天就来开盘 12 代码. 下载这个 S 代码前前后后搞了快一个月,哈哈我不愧是树懒本懒.唉,其实是中间遇到了不少问题, 环境都搞 ...

  2. android 关闭jack_Android7.0 配置JACK支持多用户同时编译

    # Android7.0 配置JACK支持多用户同时编译 reference: 背景 需要在一个Android7平台上进行有关的工作,但是编译的时候发现有问题.记录一下.因为和同事共用一台服务器,因为 ...

  3. VS 使用自带的.NET Reflector单步调试编译好的程序集(反编译),以及相关其他反编译程序介绍

    对于没有任何源代码和PDB文件的预编译程序集而言,如果没有合适的工具,调试起来并不容易.使用Red Gate的.NET Reflector可以在Visual Studio中即时反编译程序集,然后像调试 ...

  4. 使用.NET Reflector单步调试编译好的程序集

    使用.NET Reflector单步调试编译好的程序集 对于没有任何源代码和PDB文件的预编译程序集而言,如果没有合适的工具,调试起来并不容易.使用Red Gate的.NET Reflector可以在 ...

  5. Windows 10 安装 Android Studio 安装 创建APP 创建模拟器调试 真机调试 编译 签名打包APP

    要想使用Android Studio开发android APP,需要安装三个工具:JDK.Android Studio.Android SDK 先了解这三个工具是做什么的 JDK:JDK是Java语言 ...

  6. ASP.NET 2.0 中的代码隐藏和编译

    ASP.NET 2.0 中的代码隐藏和编译      Fritz Onion 本页内容 代码隐藏 编译 程序集生成 小结 当我撰写本专栏的时候,Microsoft® .NET Framework 2. ...

  7. AOSP6.0.1 launcher3入门篇—hotseat相关实现

    在安卓桌面程序的主界面我们可以看到是由QsbSearchBar(上方搜索框).Workspace(页视图空间).pageIndicator(页指示器).hotseat(底部视图空间)四个部分组成,它们 ...

  8. AOSP6.0.1 launcher3入门篇-解析DeviceProject.java及相关文件

    上一篇文章(AOSP6.0.1 launcher3入门篇-解析launcher.java文件)描述了launcher3的加载过程,本篇文章记录hotseat停靠方向和位置.隐藏页指示器.Folder大 ...

  9. Anaconda Python3.6 OpenCV4.1.0 Ubuntu 16.04源码编译

    Anaconda Python3.6 OpenCV4.1.0 Ubuntu 16.04源码编译 转载于:https://blog.csdn.net/phdsky/article/details/782 ...

最新文章

  1. 查服务器的作用有哪些,云服务器优点和功能有哪些,可以看看这些或许你会明白...
  2. 基于RTP的QOS算法简介
  3. 代码不规范?985,211也不要!
  4. linux单点登录命令,配置RHEV中LINUX 虚拟机使用ACTIVE DIRECTORY(AD域)实现单点登录的方法...
  5. multiprocessing(python 版)
  6. 配置环境_python虚拟环境的搭建
  7. html和c的区别,tn-s系统与TN-C的区别是什么
  8. main函数结束后的调用
  9. android显示字符串,Android自定义View用切图显示字符串
  10. 阿里云 蚂蚁支付宝 钉钉 c++ 面经
  11. HTML元素居中的三种方法
  12. (CVPR-2014)通过预测 10,000 个类别的深度学习人脸表示
  13. gentoo linux 内核,手动升级Gentoo及其内核的方法
  14. 建筑企业收并购的三要素
  15. Best practices for a new Go developer
  16. 重装win10系统 远程控制TeamViewer——深度学习菜鸡入门(2)
  17. 【Practical】积分第一中值定理
  18. android 系统gpu 调试_基于Android系统的GPU动态调频方案 | Imagination中文技术社区
  19. 广和通实现基于5G R16模组的FWA Open CPU方案技术突破
  20. 2021-04-27 Android 理解frameworks services jni hardware kernel 整个控制过程实例包括回调

热门文章

  1. opencv-python基础知识学习笔记
  2. 神经网络的数学表达式,神经网络的数学理论
  3. WPS—JS宏笔记记录
  4. VS2022(Visual Studio)发布ASP.NET Core Web API应用到Web服务器(IIS)
  5. python学习13:分解质因数
  6. 01、iphone越狱恢复,去越狱,手机归零
  7. OpenAi 语法修正
  8. 将自己的 ubuntu 系统制作为ISO镜像
  9. 到底要不要在office/wps平台上做开发
  10. centos:centos7.3镜像下载