Jetpack太香了,让开发效率提升了不少

news2025/1/23 6:09:16

作者:Jingle_zhang

第三方App使用Jetpack等开源框架非常流行,在Gradle文件简单指定即可。然而ROM内置的系统App在源码环境下进行开发,与第三方App脱节严重,采用开源框架的情况并不常见。但如果系统App也集成了Jetpack或第三方框架,开发效率则会大大提高。

前言

系统App开发者,很少采用Jetpack 以及第三方框架的原因主要有几点:

  1. 导入麻烦:有的框架过于庞大,可能依赖的库比较多,编译文件的构建比较繁琐,没有gradle那么智能

  2. 功能单一:系统App注重功能性,业务逻辑较少,依赖庞大库文件的场景不多

  3. license风险:引用第三方框架的话,需要特别声明license ,会尽量避免采用

但对于功能复杂,架构庞大的系统App而言,集成第三方框架显得尤为必要。比如Android系统里最核心的App SystemUI,就采用了知名的DI框架Dagger2 。Dagger2的引入使得功能庞杂的SystemUI管理各个依赖模块变得游刃有余。

SystemUI将Dagger2集成的方式给了我启发,探索和总结了Android 源码中如何配置Jetpack 以及第三方库,希望能够帮到大家。

源码编译说明

与Gradle不同,源码环境里的编译构建都是配置在.mk或者.bp文件里的,配置起来较为繁琐。

.bp文件::Android.bp是用来替换Android.mk的配置文件,它使用Blueprint框架来解析。Blueprint是生成、解析Android.bp的工具,是Soong的一部分。Soong则是专为Android编译而设计的工具,Blueprint只是解析文件的形式,而Soong则解释内容的含义,最终转换成Ninja文件。下文bp 就是指.bp的文件

**注意:**以下基于Android 11上进行的演示,Android 10及之前部分Jetpack框架没有集成进源码,需留意

gradle切换到bp

gradle和bp的对比

看一个使用aar和注解库的例子。

看一个AndroidStudio(以下简称AS)下build.gradle 文件里包的导入代码:

dependencies {
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.2.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
    //room
    def room_version = "2.3.0"
    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"
}

ROM环境里的编译依赖.bp 配置如下:

android_app {
    ......
    static_libs: [        "androidx.appcompat_appcompat",        "com.google.android.material_material",        "androidx-constraintlayout_constraintlayout",        "androidx.room_room-runtime",    ],
    plugins: ["androidx.room_room-compiler-plugin"],
    ......
}

导入关键字的差异

依赖文件里的导入关键字:

在AS和AOSP里面导入包的关键字有些差异,又分为两种情况。

build.gradle.bp
代码库implementationstatic_libs
注解使用的库annotationProcessorplugins

引入库文件(libs):比较常见。引入的方式有多种。下文会讲具体的几种方式。

引入注解库:比较流行,源码中使用比较繁琐,下文会重点讲解。

库文件的导入规则

眼尖的同学已经看出规律了

如:implementation ‘androidx.appcompat:appcompat:1.2.0’

bp 文件中:androidx.appcompat_appcompat,将“:” 改为 “”即可,不需要加版本号。其实就是group 与 name 中间用“”连接,基本上符合上述规则,当然也有特殊

注解库的导入规则

如今框架流行注解编程。

gradle 配置:annotationProcessor “androidx.room:room-compiler:$room_version”

bp 中就需要使用到plugins,对应配置plugins: [“androidx.room_room-compiler-plugin”]

根据jar 包的规则,那plugin 命名应该是“:” 改为 ”_" version+“-plugin” 。

SystemUI 使用Dagger2配置 plugins: [“dagger2-compiler-2.19”],所以命名规则并不是上文猜测的那样。

那如何确定Jetpack框架的名称呢?

确定Jetpack框架的名称

源码编译,所有的内容和都在源码中,都需要在源码环境中寻找。

以Room 为例

在prebuilts/sdk/current/androidx/Android.bp 配置了引入jar包 中有如下配置

android_library {
    name: "androidx.room_room-runtime",//名称
    ......
    manifest: "manifests/androidx.room_room-runtime/AndroidManifest.xml",//配置manifast
    static_libs: [//两个room库文件,三个依赖的库文件
        "androidx.room_room-runtime-nodeps",
        "androidx.room_room-common",
        "androidx.sqlite_sqlite-framework",
        "androidx.sqlite_sqlite",
        "androidx.arch.core_core-runtime",
    ],
}

插件配置在prebuilts/sdk/current/androidx/JavaPlugins.bp

java_plugin {
    name: "androidx.room_room-compiler-plugin",//名称
    static_libs: [//1个room库文件,1个依赖的库文件
        "androidx.room_room-compiler",
        "kotlin-reflect"
    ],
    processor_class: "androidx.room.RoomProcessor",//需要指定处理的类
}

注意:AS 开发 并不需要配置 “processor_class”,我反编译了room-compiler,找到了RoomProcessor.java.(AS 为什么不需要指定,我这里我就不研究了)

看下图,META-INF/services/javax.annotation.processing.Processor 文件中配置了RoomProcessor.java(就按照这个文件配置就可以了)

如何确定源码中哪些jetpack 库可以使用呢?

在Android.bp 中搜索,或者看androidx目录下包含了什么

prebuilts/sdk/current/androidx/m2repository/androidx$ ls

导入第三方的开源框架

以上讲的是引入Jetpack相关jar包,其他常见的是否包含呢?如Glide,它是不属于androidx 的

第三方库,Android 源码中整理就不算好了,使用比较乱。下面我梳理下

导入下载的jar包

大家最常用的,把 jar 包 放到 libs,就可以了(当然,比较简单,与其他库关联较少可以采用此种方式)

java_import {
    name: "disklrucache-jar",
    jars: ["disklrucache-4.12.0.jar"],
    sdk_version: "current",
}
android_library_import {
   name: "glide-4.12.0",
   aars: ["glide-4.12.0.aar"],
   sdk_version: "current",
}
android_library_import {
   name: "gifdecoder-4.12.0",
   aars: ["gifdecoder-4.12.0.aar",],
   sdk_version: "current",
}
android_library_import {
   name: "exifinterface-1.2.0",
   aars: ["exifinterface-1.2.0.aar",],
   sdk_version: "current",
}

android_app {
    ......
    static_libs: [
        "disklrucache-jar",
        "glide-4.12.0",
        "gifdecoder-4.12.0",
        "exifinterface-1.2.0"
    ],
}

导入AOSP内置的jar包

常用第三方放在了prebuilts/tools/common/m2/repository/下面包含了很多库文件,如Glide,Okhttp,但比较尴尬的是,.bp文件并没有写好。应用需要自己编写,编写方式可以参考上文。

以后google应该会把 external 下 的整合到这个里面,可以关注下prebuilts/tools/common/m2/repository 中Android.bp文件的变化。

如:prebuilts/maven_repo/bumptech/Android.bp

java_import {
    name: "glide-prebuilt",
    jars: [
        "com/github/bumptech/glide/glide/4.8.0/glide-4.8.0.jar",
        "com/github/bumptech/glide/disklrucache/4.8.0/disklrucache-4.8.0.jar",
        "com/github/bumptech/glide/gifdecoder/4.8.0/gifdecoder-4.8.0.jar",
    ],
    jetifier: true,
    notice: "LICENSE",
}

Android.bp 直接用"glide"了

static_libs: [
        "glide-prebuilt"
 ],

导入jar包源码

external 下面 很多第三方库的源码,如Glide的源码,目录为external/glide/

android_library {
    name: "glide",
    srcs: [
        "library/src/**/*.java",
        "third_party/disklrucache/src/**/*.java",
        "third_party/gif_decoder/src/**/*.java",
        "third_party/gif_encoder/src/**/*.java",
    ],
    manifest: "library/src/main/AndroidManifest.xml",
    libs: [
        "android-support-core-ui",
        "android-support-compat",
        "volley",
    ],
    static_libs: [
        "android-support-fragment",
    ],
    sdk_version: "current",
}

复制代码

App 的Android.bp 直接用"glide"了

static_libs: [
        "glide"
 ],

以上三种方式都是引入 Android 中源码存在的。不存在怎么办,Android源码 不像 AS,连上网,配置下版本号就可以下载。

内置新的Jetpack框架

引入第三方库文件方式,方式一:aar包导入。就可以。但这里不讨论,找些复杂的,包含annotationProcessor(bp 中的plugin) 。Hilt 是 Google 相对较新的框架。

Hilt基于Dagger2开发,又针对Android进行了专属的DI优化。

所以在导入Dagger2和它的依赖文件之外还需要导入Hilt专属的一堆库和依赖文件。

1. 获取框架的库文件

一般来说AS里导入完毕的目录下即可获取到对应的库文件,路径一般在 :C:\Users\xxx.gradle\caches\modules-2\files-2.1\com.google.dagger\hilt-android

2. 确定额外的依赖文件

为什么需要额外的依赖文件?

完全依赖AS开发可能不知道,导入的包的同时可能引入其他的包。

如Hilt的是在dagger2基础上开发,当然会引入Dagger2,

使用注解,需要javax.annotation包。

Dagger2,javax.annotation 在Gradle 自动下载好的,非项目中明确配置的,我们称之为依赖包。

使用Gradle 自动下载,都会有pom 文件。“dependency”,表示需要依赖的jar 包,还包含了版本号等

如:hilt-android-2.28-alpha.pom

`<dependency>`
  `<groupId>com.google.dagger</groupId>`
  `<artifactId>dagger</artifactId>` //依赖的dagger2
  `<version>2.28</version>`//dagger2的版本
`</dependency>`
`<dependency>`
  `<groupId>com.google.dagger</groupId>` 
  `<artifactId>dagger-lint-aar</artifactId>`
  `<version>2.28</version>`
`</dependency>`
`<dependency>`
  `<groupId>com.google.code.findbugs</groupId>`
  `<artifactId>jsr305</artifactId>`
  `<version>3.0.1</version>`
`</dependency>`
......

3. 导入需要的依赖文件

比如SystemUI,已经导入了一些文件,只要导入剩余的文件即可。

一般常用的 源码中都是存在的,决定copy 之前,可以看下先源码中是否存在,存在可以考虑使用。

当然也有例外,如Hilt 我依赖的是源码中dagger2是2.19 版本,编译中报错,没有找到dagger2 中的class,反编译jar确实不存在,使用2.28 的dagger 版本,问题就解决了。所以说可能存在库文件版本较老的情况。

以下就是新增的文件夹,其中manifests 后文中有讲。

    manifests/ 
    repository/com/google/dagger/dagger-compiler/2.28/
    repository/com/google/dagger/dagger-producers/2.28/
    repository/com/google/dagger/dagger-spi/2.28/
    repository/com/google/dagger/dagger/2.28/
    repository/com/google/dagger/hilt-android-compiler/
    repository/com/google/dagger/hilt-android/

4. 编写最终的bp文件

这一步就是把依赖的包,关联起来,根据上文的 pom 文件。

  • 配置dagger2 2.28 的jar
java_import {

name: "dagger2-2.28",

jars: ["repository/com/google/dagger/dagger/2.28/dagger-2.28.jar"],

host_supported: true,

}
  • 配置 dagger2-compiler 2.28 的jar (annotationProcessor 依赖的jar包)
java_import_host {

name: "dagger2-compiler-2.28-import",

jars: [

"repository/com/google/dagger/dagger-compiler/2.28/dagger-compiler-2.28.jar",

"repository/com/google/dagger/dagger-producers/2.28/dagger-producers-2.28.jar",

"repository/com/google/dagger/dagger-spi/2.28/dagger-spi-2.28.jar",

"repository/com/google/dagger/dagger/2.28/dagger-2.28.jar",

"repository/com/google/guava/guava/25.1-jre/guava-25.1-jre.jar",

"repository/com/squareup/javapoet/1.11.1/javapoet-1.11.1.jar",

"repository/com/google/dagger/dagger-google-java-format/1.6/google-java-format-1.6-all-deps.jar",

],
}
  • 配置dagger2 的 plugin (annotationProcessor)
java_plugin {
    name: "dagger2-compiler-2.28",
    static_libs: [
        "dagger2-compiler-2.28-import",
        "jsr330",
    ],
    processor_class: "dagger.internal.codegen.ComponentProcessor",
    generates_api: true,
}
  • 配置 hilt 依赖的aar包
android_library_import {
    name: "hilt-2.82-nodeps",
    aars: ["repository/com/google/dagger/hilt-android/2.28-alpha/hilt-android-2.28-alpha.aar"],
    sdk_version: "current",
    apex_available: [
        "//apex_available:platform",
        "//apex_available:anyapex",
    ],
    min_sdk_version: "14",
    static_libs: [
        "dagger2-2.28",
        "jsr305",
        "androidx.activity_activity",
        "androidx.annotation_annotation",
        "androidx.fragment_fragment",
    ],

}
  • 配置hilt 的包

    android_library 表示 aar 包,所以必须要配置manifests ,在上文中多出的manifasts文件夹中 放的就是这个文件,AndroidManifest.xml来自hilt-android-2.28-alpha.aar 中

android_library {
    name: "hilt-2.82",
    manifest: "manifests/dagger.hilt.android/AndroidManifest.xml",
    static_libs: [
        "hilt-2.82-nodeps",
        "dagger2-2.28"
    ],
    ......
}
  • 配置 hilt-compiler 2.82 jar包
java_import_host {
    name: "hilt-compiler-2.82-import",
    jars: [
        "repository/com/google/dagger/dagger-compiler/2.28/dagger-compiler-2.28.jar",
        "repository/com/google/dagger/dagger-producers/2.28/dagger-producers-2.28.jar",
        "repository/com/google/dagger/dagger-spi/2.28/dagger-spi-2.28.jar",
        "repository/com/google/dagger/dagger/2.28/dagger-2.28.jar",
        "repository/com/google/guava/guava/25.1-jre/guava-25.1-jre.jar",
        "repository/com/squareup/javapoet/1.11.1/javapoet-1.11.1.jar",
        "repository/com/google/dagger/dagger-google-java-format/1.6/google-java-format-1.6-all-deps.jar",
        "repository/com/google/dagger/hilt-android-compiler/2.28-alpha/hilt-android-compiler-2.28-alpha.jar",
        "repository/javax/inject/javax.inject/1/javax.inject-1.jar"
    ],
}
  • 配置hilt的 plugin (annotationProcessor)

    反编译查看需要配置的Processer

好吧,看到上图我傻眼了,11个。下文代码我只贴了一个,需要写11个,其他省略。

java_plugin {
    name: "hilt-compiler-2.82",
    static_libs: [
        "hilt-compiler-2.82-import",
        "jsr330",
    ],
    processor_class: "dagger.hilt.processor.internal.root.RootProcessor",
    generates_api: true,
}
  • 项目中引用
    `static_libs: [`
        `"androidx-constraintlayout_constraintlayout",`
        `"androidx.appcompat_appcompat",`
        `"com.google.android.material_material",`
        `"androidx.room_room-runtime",`
        `"androidx.lifecycle_lifecycle-viewmodel",`
        `"androidx.lifecycle_lifecycle-livedata",`
        `"hilt-2.82",`
        `"jsr330"`
    `],`

    `plugins: ["androidx.room_room-compiler-plugin",`
              `"hilt-compiler-2.82",`
              `"hilt-compiler-2.82-UninstallModulesProcessor",`
              `"hilt-compiler-2.82-TestRootProcessor",`
              `"hilt-compiler-2.82-DefineComponentProcessor",`
              `"hilt-compiler-2.82-BindValueProcessor",`
              `"hilt-compiler-2.82-CustomTestApplicationProcessor",`
              `"hilt-compiler-2.82-AndroidEntryPointProcessor",`
              `"hilt-compiler-2.82-AggregatedDepsProcessor",`
              `"hilt-compiler-2.82-OriginatingElementProcessor",`
              `"hilt-compiler-2.82-AliasOfProcessor",`
              `"hilt-compiler-2.82-GeneratesRootInputProcessor",`
             `],`
  • 编译确认

    编译失败了!看到报错,我的心也凉了。需要配置Gradle 插件。bp 可以配置Gradle插件?

    看了下com/google/dagger/hilt-android-gradle-plugin/,但是并不清楚bp 怎么配置,在源码里,只知道一处:prebuilts/gradle-plugin/Android.bp,但并没有尝试成功。有兴趣的同学,可以研究下。

    而且hilt-android-gradle-plugin 的jar包,依赖包 至少十几个。

public class MainActivity extends AppCompatActivity { ^ Expected @AndroidEntryPoint to have a value. Did you forget to apply the Gradle Plugin? [Hilt] Processing did not complete. See error above for details.

public class MainFragment extends BaseFragment { ^ Expected @AndroidEntryPoint to have a value. Did you forget to apply the Gradle Plugin? [Hilt] Processing did not complete. See error above for details.

public class AppApplication extends Application { ^ Expected @HiltAndroidApp to have a value. Did you forget to apply the Gradle Plugin? [Hilt] Processing did not complete. See error above for details.

虽然Hilt引入失败,但是整个过程我觉得有必要分享一下,给大家一些导入新框架的参考。

源码环境里集成开源框架的流程

常用开源框架的对照表

build.gradleAndroid.bpAOSP源码位置
androidx.appcompat:appcompatandroidx.appcompat_appcompat/sdk/current/androidx/Android.bp
androidx.core:coreandroidx.core_coreprebuilts/sdk/current/androidx/Android.bp
com.google.android.material:materialcom.google.android.material_materialprebuilts/sdk/current/extras/material-design-x/Android.bp
androidx.constraintlayout:constraintlayoutandroidx-constraintlayout_constraintlayoutprebuilts/sdk/current/extras/constraint-layout-x/Android.bp
androidx.lifecycle:lifecycle-livedataandroidx.lifecycle_lifecycle-livedataprebuilts/sdk/current/androidx/Android.bp
androidx.lifecycle:lifecycle-viewmodelandroidx.lifecycle_lifecycle-viewmodelprebuilts/sdk/current/androidx/Android.bp
androidx.recyclerview:recyclerviewandroidx.recyclerview_recyclerviewprebuilts/sdk/current/androidx/Android.bp
androidx.annotation:annotationandroidx.annotation_annotationprebuilts/sdk/current/androidx/Android.bp
androidx.viewpager2:viewpager2androidx.viewpager2_viewpager2prebuilts/sdk/current/androidx/Android.bp
androidx.room:room-runtimeandroidx.room_room-runtimeprebuilts/sdk/current/androidx/Android.bp
glideglide-prebuiltprebuilts/maven_repo/bumptech/Android.bp
gsongson-prebuilt-jarprebuilts/tools/common/m2/Android.bp
Robolectric相关Robolectric相关prebuilts/tools/common/m2/robolectric.bp

经验总结

1、build.gradle 需要配置 额外插件的,如hilt、databinding viewbinding 不建议使用源码编译。

2、建议使用 AOSP 源码 中 bp 已经配置好的。这样就可以直接使用了。

3、jetpack 包引入或者androidx 引入,建议先prebuilts/sdk/current/androidx 下寻找配置好的bp 文件

4、非androidx ,建议先在prebuilts/tools/common/m2下寻找寻找配置好的bp 文件

5、文章中的例子都是prebuilts目录下配置,项目中使用,也可以配置在项目中,都是可以的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/397150.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【UE4 RTS游戏】04-摄像机运动_鼠标移动到视口边缘时移动Pawn

效果可以看到当鼠标移动到视口边缘时&#xff0c;Pawn就会向这个方向移动。步骤打开项目设置&#xff0c;添加两个操作映射打开“CameraPawnController”&#xff0c;在事件图表中添加两个浮点型变量&#xff0c;一个为公有一个为私有。分别命名为“ZoomSensitivity”、“MaxAr…

【Linux】帮助文档查看方法

目录1 Linux帮助文档查看方法1.1 man1.2 内建命令(help)1 Linux帮助文档查看方法 1.1 man man 是 Linux 提供的一个手册&#xff0c;包含了绝大部分的命令、函数使用说明。 该手册分成很多章节&#xff08;section&#xff09;&#xff0c;使用 man 时可以指定不同的章节来浏…

ubuntu 系统安装docker——使用docker打包python项目,整个流程介绍

目录 1 安装docker和配置镜像源 2 下载基础镜像 3 通过镜像创建容器 4 制作项目所需的容器 5 容器制作好后打包为镜像 6 镜像备份为.tar文件 7 从其他服务器上恢复镜像 8 docker的其他常用指令 首先科普一下镜像、容器和实例&#xff1b; 镜像&#xff1a;相当于安装包&…

怎么用消息队列实现分布式事务?

当消息队列和事务联系在一起时&#xff0c;它指的是消息生产者和消息消费者之间如何保持数据一致性。 什么是分布式事务&#xff1f; 事务是指当我们进行若干项数据更新操作时&#xff0c;为了保证数据的完整性和一致性&#xff0c;我们希望这些更新操作要么都成功&#xff0…

蓝桥杯三月刷题 第五天

文章目录&#x1f4a5;前言&#x1f609;解题报告&#x1f4a5;数的分解&#x1f914;一、思路:&#x1f60e;二、代码&#xff1a;&#x1f4a5;前言 上午没写&#xff0c;下午写了会被朋友拉出去耍&#xff0c;被冷风吹到了&#xff0c;而且被他坑了&#xff0c;根本没有玩骑…

【源码库】在调用 createApp 时,Vue 为我们做了那些工作?

在使用Vue3时&#xff0c;我们需要使用createApp来创建一个应用实例&#xff0c;然后使用mount方法将应用挂载到某个DOM节点上。 那么在调用createApp时&#xff0c;Vue再背后做了些什么事情呢&#xff1f;今天就来扒一扒Vue3的源码&#xff0c;看看调用createApp发生了些什么…

八股文系列:Java虚拟机(JVM)

说一下 JVM 的主要组成部分及其作用&#xff1f; JVM包含两个子系统和两个组件&#xff0c;两个子系统为Class loader(类装载)、 Execution engine(执行引擎)&#xff1b;两个组件为Runtime data area(运行时数据 区)、Native Interface(本地接口)。 Class loader(类装载)&…

IDEA插件开发入门.02

前言许久没更新IDEA插件开发系列了。最近刚好在汇总日常开发中常见的代码“异味”&#xff0c;共享文档复制黏贴略显麻烦&#xff0c;所以想着是否可以搞一个IDEA插件来帮忙收集常见代码&#xff0c;毕竟IDEA作为后端程序员必备的开发工具&#xff0c;显然会方便很多。于是&…

【JavaEE初阶】第四节.文件操作 和 IO (上篇)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、文件 1.1 文件的概念 1.2 文件的路径二、 Java中文件系统操作 2.1 File类的属性 2.2 File类的构造方法 2.3 File类的方法 …

ArangoDB

介绍 ArangoDB 是一个原生的多模型开源数据库&#xff0c;具有灵活的文档、图形和键值数据模型。使用方便的类似 SQL 的查询语言或 JavaScript 扩展构建高性能应用程序。主要特点 在集群上安装 ArangoDB —— 安装简单灵活的数据建模&#xff1a;数据建模为键值对、文档或图表的…

企业信息化,电商商品详情API接口,数据返回值说明,商品详情,关键词搜索,价格监控,卖家买家订单等相关数据

都在说API&#xff0c;API到底是什么&#xff1f; 对于很多非IT人士而言&#xff0c;API ≈ 听不懂。 其实日常生活中&#xff0c;我们有很多类似API的场景&#xff0c;比如&#xff1a; 电脑需要调用手机里面的信息&#xff0c;这时候你会拿一根数据线将电脑手机连接起来&a…

[Tomcat]解决IDEA中的Tomcat中文乱码问题

目录 1、IDEA 2、VM options 3、IDEA启动程序的存放目录 4、Tomcat 写在前面&#xff1a;此方法亲测有效&#xff01;&#xff01;&#xff01; 1、IDEA 2、VM options 加上这两行&#xff1a; -Dfile.encodingUTF-8 -Dconsole.encodingUTF-8 3、IDEA启动程序的存放目录…

置信椭圆(误差椭圆)详解

文章目录Part.I 预备知识Chap.I 一些概念Chap.II 主成分分析Chap.III Matlab 函数 randnChap.IV Matlab 函数 pcaPart.II 置信椭圆的含义Chap.I 一个 Matlab 实例Sec.I 两个不相关变量的特征Sec.II 两个相关变量的特征Chap.II 变换阵 (解相关矩阵) 的求解ReferencePart.I 预备知…

配置VM虚拟机Centos7网络

配置VM虚拟机Centos7网络 第一步&#xff0c;进入虚拟机设置选中【网络适配器】选择【NAT模式】 第二步&#xff0c;进入windows【控制面板\网络和 Internet\网络连接】设置网络状态。 我们选择【VMnet8】 点击【属性】查看它的网络配置 2 .我们找到【Internet 协议版本 4(TCP…

一小时快速上手GoWeb开发之Gin框架

Go是一门正在快速增长的编程语言&#xff0c;专为构建简单、快速且可靠的软件而设计。golang提供的net/http库已经很好了&#xff0c;对于http的协议的实现非常好&#xff0c;基于此再造框架&#xff0c;也不会是难事&#xff0c;因此生态中出现了很多框架。 Gin&#xff1a;G…

【rust-grpc-proxy】在k8s中,自动注入代理到pod中,再不必为grpc调试而烦恼

目录前言原理sidecarwebhook实现安装k8s设置webhook使用尾语前言 rust-grpc-proxy 目前功能基本完善。是时候上环境开始应用了。 之前考虑是gateway模式或者sidecar模式。 思考良久之后&#xff0c;觉得两种模式都有使用场景&#xff0c;那就都支持。本次就带来sidecar模式的食…

实战小项目之视频监控(1-1)

实战小项目之视频监控&#xff08;1-1&#xff09; 目前常见的视频监控和视频直播都是使用了 RTMP 和 RTSP 流媒体传输协议等。 RTSP&#xff08;Real-Time Stream Protocol&#xff09;由 Real Networks 和 Netscape 共同提出的&#xff0c;基于文本的多媒体播放 控制协议。…

计算机科学导论笔记(五)

目录 七、操作系统 7.1 引言 7.1.1 操纵系统 7.1.2 自举过程 7.2 演化 7.3 组成部分 7.3.1 用户界面 7.3.2 内存管理器 7.3.3 进程管理器 7.3.4 设备管理器 7.3.5 文件管理器 7.4 操作系统 7.4.1 UNIX 7.4.2 Linux 7.4.3 Windows 七、操作系统 7.1 引言 计算机…

阿里云手机短信登录

阿里云短信服务介绍阿里云短信服务&#xff08;Short Message Service&#xff09;是广大企业客户快速触达手机用户所优选使用的通信能力。调用API或用群发助手&#xff0c;即可发送验证码、通知类和营销类短信&#xff1b;国内验证短信秒级触达&#xff0c;到达率最高可达99%&…

三维重建(单目、双目、多目、点云、SFM、SLAM)

1 相机几何与标定1.1 相机模型中的坐标系1.2 四种坐标系之间的转换1.3 相机内参1.4 相机标定2 单目三维重建2.1 NeuralRecon三维重建定义 在计算机视觉中, 三维重建是指根据单视图或者多视图的图像重建三维信息的过程. 由于单视频的信息不完全,因此三维重建需要利用经验知识. 而…