当前位置: 首页 > news >正文

深入了解 Android 中的应用程序签名

深入了解 Android 中的应用程序签名

  • 一、应用程序签名介绍
    • 1.1 应用程序签名
    • 1.2 应用程序签名的意义
    • 1.3 应用程序签名的流程
    • 1.4 应用程序签名的方案
    • 1.5 签名的重要性和应用场景
  • 二、AOSP 的应用签名
    • 2.1 AOSP的应用签名文件路径
    • 2.2 应用程序指定签名文件
  • 三、Android Studio 的应用签名
    • 3.1 Android Studio 签名步骤
    • 3.2 Android Studio 选择签名方案
    • 3.3 应用重新签名
  • 四、签名文件及其工具
    • 4.1 签名文件
    • 4.2 工具 apksigner
    • 4.3 工具 keytool
    • 4.4 签名证书格式转换
  • 五、总结

在 Android 应用程序的发布过程中,APK 的签名是一项至关重要的任务。签名确保应用程序的完整性、真实性和安全性。在 AOSP 中,开发者可以使用强大的 apksigner 工具进行 APK 签名。签名 APK 是一个重要的过程,用于验证 APK 的完整性和真实性。在进行签名之前,确保你已经熟悉签名流程,并且对密钥库的管理和安全性有所了解。

一、应用程序签名介绍

1.1 应用程序签名

应用程序签名是将数字签名应用于 Android 应用程序(APK 文件)的过程。它使用密钥对对应用程序进行加密,确保在应用程序发布和分发过程中的完整性和真实性。

1.2 应用程序签名的意义

  • 验证完整性:签名可确保 APK 文件在传输或分发过程中没有被篡改或损坏。
  • 验证真实性:签名允许用户验证应用程序的来源和开发者身份,以确保 APK 来自可信的来源。
  • 安全性:签名可以防止恶意用户在未经授权的情况下更改应用程序的代码或资源。

1.3 应用程序签名的流程

(1)生成密钥库:首先,开发者需要使用 keytool 工具生成一个密钥库(JKS 文件),其中包含用于签名的密钥对。
(2)配置构建脚本:开发者需要在构建脚本(如 build.gradle)中配置签名相关的信息,包括密钥库的路径、别名和密码等。
(3) 使用 apksigner 工具进行签名:在构建过程的最后阶段,使用 apksigner 工具对 APK 进行签名,并输出签名后的 APK 文件。

在这里插入图片描述

1.4 应用程序签名的方案

(1)APK 签名方案 V1(JAR 签名)

传统的 APK 签名方案,兼容所有 Android 版本。使用 JAR 签名对 APK 进行签名。

(2)APK 签名方案 V2

引入了增强的签名机制和对 APK 内容的完整性校验。适用于 Android 7.0。

(3)APK 签名方案 V3

引入了进一步增强的签名机制和对 APK 内容的完整性校验。适用于 Android 9.0 及更高版本。

应用签名:https://source.android.com/docs/security/features/apksigning?hl=zh-cn

1.5 签名的重要性和应用场景

(1) 系统应用签名:在 AOSP 中,系统应用必须进行签名,以确保系统的完整性和安全性。
(2) Google Play Store 发布要求:如果你计划将应用程序上传到 Google Play Store,它必须使用符合要求的签名方案进行签名。
(3) 应用程序验证和更新:签名允许设备验证应用程序的完整性,并支持应用程序的安全更新。

二、AOSP 的应用签名

2.1 AOSP的应用签名文件路径

AOSP的应用签名文件位于 /build/target/product/security 目录下。该目录下包含四个签名文件:

  • testkey.x509.pem:用于签名测试应用程序的签名文件。
  • platform.x509.pem:用于签名系统应用程序的签名文件。
  • shared.x509.pem:用于签名需要与 home/contacts 进程共享数据的应用程序的签名文件。
  • media.x509.pem:用于签名 media/download 系统中的应用程序的签名文件。
    在这里插入图片描述

默认情况下,AOSP 使用 testkey.x509.pem 签名所有应用程序。如果要为应用程序使用其他签名文件,可以将签名文件复制到 /build/target/product/security 目录下,并在应用程序的 Android.mk 文件中指定签名文件的名称。

2.2 应用程序指定签名文件

AOSP 使用 Android.mk 配置文件编译代码,LOCAL_CERTIFICATE 属性用于为应用程序指定签名文件

LOCAL_CERTIFICATE := testkey

如果您要为应用程序使用自定义签名文件,可以使用 LOCAL_CERTIFICATE_FILE 变量指定签名文件的路径。

LOCAL_CERTIFICATE_FILE := $(LOCAL_PATH)/my_key.pem

请注意,AOSP 中的签名文件都是 .pem 格式的 X.509 证书文件。

三、Android Studio 的应用签名

3.1 Android Studio 签名步骤

  1. 在工具栏中,单击 Build > Generate Signed APK
  2. Key Store Path 字段中,指定密钥库文件的路径。
  3. Key Store Password 字段中,输入密钥库的密码。
  4. Key Alias 字段中,输入密钥的别名。
  5. Key Password 字段中,输入密钥的密码。
  6. 单击 Generate

Android Studio 将生成一个新的 APK 文件,该文件将使用指定的密钥进行签名的。

也可以直接在app目录下的build.gradle文件中的android{}下配置签名,参考如下:

signingConfigs {release {storeFile file(rootProject.storeFile)storePassword rootProject.storePasswordkeyAlias rootProject.keyAliaskeyPassword rootProject.keyPassword}
}buildTypes {release {signingConfig signingConfigs.releaseminifyEnabled trueproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}
}

3.2 Android Studio 选择签名方案

旧版本的 Android Studio 可以选择 V1 或 V2 签名方案,新版本的Android Studio(Android Studio Hedgehog | 2023.1.1)没有此选项了,默认是只有 V2 签名。

server@dev-fj-srv:~$ apksigner verify -verbose demo-release.apk 
Verifies
Verified using v1 scheme (JAR signing): false
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): false
Verified using v4 scheme (APK Signature Scheme v4): false
Verified for SourceStamp: false
Number of signers: 1

如果需要使用V2方案签名,可以修改signingConfigs配置,添加enableV1SigningenableV2SigningenableV3SigningenableV4Signing,参考如下:

signingConfigs {release {storeFile file(rootProject.storeFile)storePassword rootProject.storePasswordkeyAlias rootProject.keyAliaskeyPassword rootProject.keyPasswordenableV1Signing trueenableV2Signing trueenableV3Signing trueenableV4Signing true}
}

或者使用命令行,借助apksigner工具签名,输入命令:

apksigner sign --v1-signing-enabled true --v2-signing-enabled true --v3-signing-enabled true --ks platform.jks unsigned.apk

apksigner是工具名称,–v1-signing-enabled true表示添加v1签名,本次命令同时添加v1、v2和v3签名,均使用platform.jks证书。

但是实际测试下来,enableV2SigningenableV3Signing是可以控制的,enableV1SigningenableV4Signing控制无效。

3.3 应用重新签名

apksigner 提供了对 APK 文件进行签名的命令行语法如下:

apksigner sign --ks keystore_path --ks-key-alias alias_name --out output_apk input_apk

这里是每个参数的说明:

  • sign:指定要执行的操作为签名操作。
  • --ks keystore_path:指定密钥库(JKS 文件)的路径。
  • --ks-key-alias alias_name:指定要用于签名的密钥库中的别名。
  • --out output_apk:指定签名后的 APK 文件的输出路径和文件名。
  • input_apk:指定要签名的原始 APK 文件的路径和文件名。

你需要替换命令中的 keystore_pathalias_nameoutput_apkinput_apk 为实际的值。在运行命令之前,请确保已经安装并正确配置了 apksigner 工具,以及提供了有效的密钥库和别名。此外,还需要确保你具有对密钥库的访问权限,并且了解密钥库和别名的密码。

四、签名文件及其工具

4.1 签名文件

PEM、JKS(Java KeyStore)、PK8 文件的简要对比表

特征PEM 文件JKS 文件PK8 文件
格式文本格式,Base64 编码的 ASCII 文件二进制格式的 Java KeyStore 文件二进制格式的私钥文件
用途证书、私钥、公钥交换存储密钥、证书链存储 PKCS#8 格式的私钥
支持内容通常包括证书(X.509)、私钥证书、私钥、根证书、中间证书等私钥
扩展名.pem.crt.key.jks.keystore.pk8
密码保护可选,可以使用密码保护私钥是,可以为整个 KeyStore 设置密码可选,可以使用密码保护私钥
常见工具OpenSSLJava Keytool,KeyStore Explorer 等通常用于 Android 签名工具
平台兼容性跨平台主要用于 Java 环境主要用于 Android 签名

PEM 文件和 JKS 文件是用于存储密钥和证书的通用格式,而 PK8 文件则是特定于 Android 平台的私钥文件格式。PEM 文件通常用于存储 SSL/TLS 证书,而 JKS 文件通常用于存储 Android 应用程序的签名证书。

  1. PEM 文件(Privacy-Enhanced Mail)

PEM 是一种基于文本的文件格式,用于存储密钥和证书。PEM 文件使用 Base64 编码,以便在文本文件中进行传输和处理。PEM 文件通常用于存储证书、私钥以及其他与密钥和证书相关的信息。

PEM 文件的内容通常以"-----BEGIN…“和”-----END…"标记包围的块形式呈现。PEM 文件可以包含不同类型的内容,例如公钥、私钥、证书请求(CSR)和 CA 根证书等。 PEM 格式支持的算法包括 RSA、DSA 和 ECDSA 等。

  1. JKS 文件(Java KeyStore)

JKS 是 Java KeyStore 的缩写,是 Java 平台下的一种密钥存储格式。JKS 文件是二进制格式的密钥库,用于存储密钥、证书和可信任的证书颁发机构(CA)证书。

JKS 文件是 Java KeyStore 类的默认格式,它可以包含多个条目,每个条目都有一个别名(Alias)和相应的密钥或证书。JKS 文件通常在 Java 程序和框架中使用,用于管理密钥和证书。JKS 格式支持的算法包括 RSA、DSA 和 ECDSA,以及更多的加密和签名算法。

  1. PK8 文件

PK8 文件是一种用于存储私钥的文件格式。PK8 文件通常用于 Android 平台中,用于存储应用程序的私钥。这些私钥用于应用的签名和应用发布过程中的安全验证。

PK8 文件是基于 DER(Distinguished Encoding Rules)编码的,是一种二进制格式。它通常包含应用的私钥,用于对应用进行数字签名。

PK8 文件是存储 PKCS#8 格式的私钥的二进制文件。通常用于 Android 平台的应用签名,Android 签名工具使用的是这种格式的私钥。

4.2 工具 apksigner

apksigner 是 Android SDK 中的一个命令行工具,用于对 APK 文件进行签名和验证。它是 Android 7.0(API 级别 24)及更高版本引入的工具,用于替代之前的 jarsigner 工具。

apksigner 提供了更高级的 APK 签名功能,包括 APK 签名方案 v2 和 v3 的支持。它还可以验证 APK 的签名,以确保 APK 文件未被篡改,并且可以提供关于 APK 签名的详细信息。你可以通过以下步骤获取 apksigner 工具:

  1. 安装 Android SDK:首先,确保你已经安装了 Android SDK(Software Development Kit)。Android SDK 可以从 Android 开发者网站(https://developer.android.com/studio)上下载和安装。

  2. 配置环境变量:将 Android SDK 的 build-tools 目录路径添加到系统的环境变量中。这个目录包含了 apksigner 工具。具体路径可能因你的 Android SDK 安装位置和版本而有所不同。

  3. 检查 apksigner 工具:打开命令行终端,并输入以下命令来验证 apksigner 是否正确安装:

apksigner --version

如果 apksigner 安装正确,将显示 apksigner 的版本信息。apksigner 是在 Android SDK 的 build-tools 目录中提供的,因此你需要确保你已经安装了相应版本的 build-tools

除了 apksigner ,还有一个类似的工具 jarsigner
用途:
(1) jarsigner 是 Java 开发工具包(Java Development Kit,JDK)中的一部分,主要用于对 JAR 文件进行数字签名。它不是专门设计用于 Android APK 文件的。
(2) apksigner 是 Android SDK(Software Development Kit)的一部分,专门设计用于对 Android APK 文件进行数字签名。它提供了更多与 Android 签名相关的功能,并支持 APK Signature Scheme v2、v3、v4 等 Android 特定的签名方案。

签名方案:
(1) jarsigner 主要支持 Java Keystore(JKS)格式,并使用 JAR 签名规范。在 Android 中,它可以用于签名 APK,但可能无法充分利用 Android 平台引入的新签名方案。
(2) apksigner 是专为 Android APK 文件设计的,支持 APK Signature Scheme v2、v3、v4 等。这些签名方案提供了更强大的安全性和验证功能,且 apksigner 是 Android 官方推荐的签名工具。

🚀 apksigner 命令中的常用选项和用法

  1. APK 签名
apksigner sign --ks keystore.jks --ks-key-alias mykey --out signed.apk unsigned.apk

这个命令使用名为 keystore.jks 的密钥库文件中的 mykey 别名下的密钥对 unsigned.apk 进行签名,并将签名后的 APK 保存为 signed.apk。

  1. 查看 APK 签名信息
apksigner verify --print-certs signed.apk

这个命令验证并打印 signed.apk 中的签名信息和证书链。

  1. 验证 APK 完整性
apksigner verify --verbose signed.apk

这个命令验证 signed.apk 的完整性,并显示详细的验证结果。

  1. 检查 APK 签名版本
apksigner verify --verbose --print-certs signed.apk | grep "Signer #"

这个命令检查 signed.apk 中使用的 APK 签名方案版本。

  1. 提取 APK 签名证书
apksigner extract-cert --verbose --cert pem --out certificate.pem signed.apk

这个命令从 signed.apk 中提取签名证书,并将其保存为 certificate.pem 文件。

使用 apksigner --help 命令查看更多的选项和帮助信息。

4.3 工具 keytool

keytool 是 Java 开发工具包(JDK)中的一个命令行实用程序,用于创建和管理密钥库(KeyStore)和相关的数字证书。它提供了一组功能来生成密钥对、生成证书签名请求、导入和导出证书等操作,以及管理密钥库的密码和别名。

keytool 是一个强大而灵活的工具,通常用于与公钥基础设施(Public Key Infrastructure,PKI)相关的任务,例如在开发和部署 Java 应用程序时使用数字证书进行身份验证和数据加密。

要使用 keytool,需要安装 Java Development Kit(JDK)并设置正确的环境变量。然后可以在命令行中使用 keytool 命令,并提供相应的选项和参数来执行所需的操作。

🚀 keytool 命令中的常用选项和用法

  1. 生成密钥对(Key Pair)
keytool -genkeypair -alias mykey -keyalg RSA -keysize 2048 -keystore keystore.jks

这个命令生成一个 RSA 密钥对,并将其存储在名为 mykey 的别名下,保存在名为 keystore.jks 的密钥库文件中。

  1. 查看密钥库内容
keytool -list -keystore keystore.jks

这个命令显示密钥库文件 keystore.jks 中存储的密钥和证书的详细信息。

  1. 导出证书
keytool -export -alias mykey -file certificate.crt -keystore keystore.jks

这个命令将别名为 mykey 的证书导出到名为 certificate.crt 的文件中。

  1. 导入证书
keytool -import -alias mykey -file certificate.crt -keystore keystore.jks

这个命令将名为 certificate.crt 的证书导入到密钥库文件 keystore.jks 中,使用别名 mykey

  1. 更改密钥库密码
keytool -storepasswd -keystore keystore.jks

这个命令用于更改密钥库文件 keystore.jks 的密码。

  1. 更改密钥密码
keytool -keypasswd -alias mykey -keystore keystore.jks

这个命令用于更改别名为 mykey 的密钥的密码。

使用 keytool -help 命令查看更多的选项和帮助信息。

4.4 签名证书格式转换

JKS(Java KeyStore)和 PEM(Privacy Enhanced Mail)是两种不同的密钥存储和交换格式。以下是在两者之间进行互转的方法:

(1) JKS 到 PEM

  1. 导出证书和私钥到 PKCS12 格式:
    keytool -importkeystore -srckeystore your_keystore.jks -destkeystore keystore.p12 -srcstoretype JKS -deststoretype PKCS12
    

参数说明:

  • keytool:用于管理密钥和证书的命令行工具。
  • -importkeystore:用于将密钥库从一种格式转换为另一种格式的命令。Android stduio v3签名
  • -srckeystore:指定源密钥库文件的路径。
  • -destkeystore:指定目标密钥库文件的路径。
  • -deststoretype:指定目标密钥库的类型。
  1. 导出证书和私钥到 PEM 格式:

    openssl pkcs12 -in keystore.p12 -out keystore.pem
    
  2. 提取私钥:

    openssl rsa -in keystore.pem -out private-key.pem
    
  3. 提取证书:

    openssl x509 -in keystore.pem -out certificate.pem
    

(2) PEM 到 JKS

  1. 将私钥和证书合并成 PKCS12 格式:

    openssl pkcs12 -export -out keystore.p12 -inkey private-key.pem -in certificate.pem
    
  2. 将 PKCS12 导入到 JKS:

    keytool -importkeystore -srckeystore keystore.p12 -srcstoretype PKCS12 -destkeystore your_keystore.jks -deststoretype JKS
    

在这些步骤中,your_keystore.jks 是原始的 JKS 文件,private-key.pemcertificate.pem 是 PEM 格式的私钥和证书文件。在实际操作中,确保替换这些文件名和路径为你实际的文件名和路径。

请注意,这些命令假设你的系统上已经安装了 OpenSSL 工具和 Java Keytool。在执行这些命令之前,请备份你的密钥库和证书,以避免意外丢失数据。

五、总结

在 Android 开发中,应用程序签名是一个重要的步骤,用于确保应用程序的完整性、真实性和安全性。AOSP 提供了强大的 apksigner 工具,可用于对 APK 进行签名。开发者需要选择适合的签名方案,并遵循最佳实践和安全建议来保护密钥库和签名的安全性。

相关参考
[1] SigningConfig:https://developer.android.com/reference/tools/gradle-api/7.0/com/android/build/api/variant/SigningConfig
[2] apksigner:https://developer.android.com/studio/command-line/apksigner?hl=zh-cn#usage-rotate
[3] keytool:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html
[4] 为应用签名:https://developer.android.com/studio/publish/app-signing?hl=zh-cn
[5] 证书格式转换:https://myssl.com/cert_convert.html

相关文章:

深入了解 Android 中的应用程序签名

深入了解 Android 中的应用程序签名 一、应用程序签名介绍1.1 应用程序签名1.2 应用程序签名的意义1.3 应用程序签名的流程1.4 应用程序签名的方案1.5 签名的重要性和应用场景 二、AOSP 的应用签名2.1 AOSP的应用签名文件路径2.2 应用程序指定签名文件 三、Android Studio 的应…...

说说 style gan 中的感知路径长度(Perceptual Path Length)

我在之前的博库中介绍了 style gan 的基本原理,原文中有提出感知路径长度(Perceptual Path Length)的概念。这是一种评价生成器质量的方式。 PPL基本思想:给出两个随机噪声 z 1 , z 2 ​ ,为求得两点的感知路径长度PPL…...

基于JAVA的厦门旅游电子商务预订系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 景点类型模块2.2 景点档案模块2.3 酒店管理模块2.4 美食管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 学生表3.2.2 学生表3.2.3 学生表3.2.4 学生表 四、系统展示五、核心代码5.1 新增景点类型5.2 查询推荐的…...

uniapp中使用封装步骤条组件

针对步骤条封装完终于清清楚楚啦 先看效果&#xff1a; 附上代码&#xff1a;使用可直接复用&#xff1a;数据是写在了当前组件中&#xff0c;如有必须&#xff0c;可以使用其中的props传值stepInfos传递相应的数据&#xff0c;根据steps步数就可以控制走到哪一步啦 <temp…...

【MySQL】sum 函数和 count 函数的相同作用

力扣题 1、题目地址 1174. 即时食物配送 II 2、模拟表 配送表&#xff1a;Delivery Column NameTypedelivery_idintcustomer_idintorder_datedatecustomer_pref_delivery_datedate delivery_id 是该表中具有唯一值的列。该表保存着顾客的食物配送信息&#xff0c;顾客在某…...

在QT Creator下用CMake编译GEOS库

最近&#xff0c;想要在C下编一个可用GDAL模块的地图管理系统&#xff0c;找来找去&#xff0c;找到了GEOS。GEOS&#xff08;Geometry Engine-Open Source&#xff09;开源几何引擎 是一个用于计算几何的JTS库的 C/C实现&#xff0c;专注于地理信息系统 &#xff08;GIS&#…...

【Qt之Quick模块】4. QML语法格式及命名规范

概述 QML&#xff08;Qt Meta-Object Language&#xff09;是一种声明式语言&#xff0c;用于设计用户界面。它是由Qt框架提供的一种描述界面组件的语言&#xff0c;可以与C代码结合使用&#xff0c;用于创建跨平台的应用程序。 QML具有以下特点&#xff1a; 声明式&#xff…...

Python内置类属性__class__属性的使用教程

概要 Python作为一种高级编程语言&#xff0c;提供了丰富的功能和灵活性&#xff0c;使得开发人员能够更加方便地处理各种任务。其中一个强大的功能是内置类属性__class__属性。本文将详细介绍__class__属性的用法&#xff0c;帮助读者更好地理解和利用这一功能。 第一部分&am…...

【后台报错】插入时sql报错,varchar撑爆

后台的一个报错。按照正常的需要复现&#xff0c;或者查一下日志。但是凭借多年经验和大胆猜测&#xff0c;以及对自己代码要自信 引用一下文章 目测7*15 105项。每个id有9个数字加上分隔符刚好十个。大概就是超过了定义的一千的varchar长度。直接改数据库就好了。 简单粗暴…...

OpenSergo使用详解

简介 OpenSergo是一个基于微服务治理的标准和生态&#xff0c;覆盖了服务元信息、流量治理、服务容错、数据库/缓存治理、服务注册发现、配置治理等十几个关键领域&#xff0c;覆盖了完整的微服务生命周期&#xff08;从开发态到测试态&#xff0c;到发布态&#xff0c;再到运…...

Vanilla Pro for Mac 一款隐藏菜单栏图标工具

Vanilla Pro Vanilla Pro是一款简单易于使用的Mac应用程序&#xff0c;可让您隐藏菜单栏图标。只需下载Vanilla&#xff0c;启动应用程序&#xff0c;然后按照提示即可开始。 资源获取 Vanilla Pro for Mac 功能特性 键盘快捷键&#xff1a;设置自定义键盘快捷键来切换菜单…...

freemarkEngine文件ftl的可视化编辑

在做导出word文件功能时&#xff0c;需要准备ftl模板&#xff0c;设置一些通配符&#xff0c;之后通过相关编码&#xff0c;即可以实现业务数据渲染后导出word的功能。但是ftl文件一般我们看不太懂&#xff0c;所以可视化创建和修改就非常合适。 1、安装office2016版本&#x…...

2023 英特尔On技术创新大会直播 | 边云协同加速 AI 解决方案商业化落地

目录 前言边云协同时代背景边缘人工智能边缘挑战英特尔边云协同的创新成果最后 前言 最近观看了英特尔On技术创新大会直播&#xff0c;学到了挺多知识&#xff0c;其中对英特尔高级首席 AI 工程张宇博士讲解的边云协同加速 AI 解决方案商业化落地特别感兴趣。张宇博士讲解了英…...

Q-star计划的更多细节

继续探讨点Q*相关的话题,这个应该是目前X和Reddit上比较火的话题了,其实就是关于Q*的方法是不是让LLM变得会产生意识,会产生自己的好恶和对人类的偏见,关于Q-star的一些介绍可以看我上一篇的扫盲帖 RLAIF方法与传说中的函数Q,揭露OpenAI那不为人知的Qstar计划 (qq.com) 我…...

python3 数据分析项目案例,用python做数据分析案例

本篇文章给大家谈谈python3 数据分析项目案例&#xff0c;以及用python做数据分析案例&#xff0c;希望对各位有所帮助&#xff0c;不要忘了收藏本站喔。 目录 一丶可视化绘图案例 1.曲线图 2.柱形图 3.点线图 4.3D散点图 5. 绘制漏斗图 6. 绘制词云图 二丶包/模块使用示例 (1)…...

Android 12 (InputMethodManagerService) 替换默认输入法为Pinyin输入法

1.问题场景 由于系统自带的Latin输入法不支持遥控器操作&#xff0c;需要替换为RK的拼音输入法。 2. 替换步骤 1&#xff09;将LatinIME从mk中删除&#xff0c;让系统编译的时候不编译该apk --- a/Android/build/make/target/product/handheld_product.mkb/Android/build/m…...

【模式识别】探秘判别奥秘:Fisher线性判别算法的解密与实战

​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《模式之谜 | 数据奇迹解码》⏰诗赋清音&#xff1a;云生高巅梦远游&#xff0c; 星光点缀碧海愁。 山川深邃情难晤&#xff0c; 剑气凌云志自修。 目录 &#x1f30c;1 初识模式识…...

【XML】TinyXML 详解

1、简介 优点&#xff1a; TinyXML 是一个简单、小型的 C XML 解析器&#xff0c;可以轻松集成到项目中。 TinyXML 解析 XML 文档&#xff0c;并根据该文档构建可读取、修改和保存的文档对象模型 (DOM) TinyXML 是在 ZLib 许可下发布的&#xff0c;因此可以在开源或商业代码中…...

泛社交裂变场景下AB增量科学评估方案

在数据驱动业务的大环境下&#xff0c;AB实验是对策略效果进行评估的重要指南针&#xff0c;并广泛应用在用增/推荐/搜索/内容/商业化等多个领域&#xff0c;尤其是综合评估多个策略对于大盘影响的对比效果&#xff0c;AB增量的计算就尤为重要。 背景 现在普遍常见的泛社交裂变…...

【无标题】json报错

操作失败&#xff0c;JSON parse error: Cannot deserialize value of type com.alibaba.fastjson.JSONArray from String value (token JsonToken.VALUE_STRING); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize valu…...

MyBatis中延迟加载,全局和局部的开启使用与关闭

文章目录 MyBatis中延迟加载&#xff0c;全局和局部的开启使用与关闭1、问题提出2、延迟加载和立即加载延迟加载立即加载 3、三种对应的表关系中的加载4、打开全局延迟加载&#xff08;实现一对一的延迟加载&#xff09;5、实现一对多的延迟加载&#xff08;将上面设置的全局延…...

MyBatis增删改查基础及其xml文件

目录 一.增删改查基础 1.增 增Insert 获取自增ID 对insert参数进行重命名 2.删 3.改 4.查 1)对MySQL查询结果进行重命名 从MySQL层面--as 从mybatis层面--Results注解 复用Results的定义 2)配置自动转换驼峰命名&#xff08;推荐&#xff09; 二.Mybatis xml配置…...

视觉学习(1)—— 理论

一、提问 初入视觉的几个问题&#xff1a; 1、视觉是怎么被控制的 2、怎么让视觉启动 3、视觉需要完成什么东西 4、视觉启动如何将完成的东西反馈给我 二、回答 1、视觉都是通过通讯协议控制&#xff0c;如串口、Modbus TCP等协议 2、视觉中的所有功能块都在流程中&…...

pip 常用指令 pip list 命令用法介绍

&#x1f4d1;pip 常用命令归类整理 pip list 是一个用于列出已安装的 Python 包的命令。这个命令会显示出所有已安装的包&#xff0c;以及它们的版本号。 pip list 命令有以下参数 -o, --outdated&#xff1a;列出所有过时的包&#xff0c;即有新版本可用的包。-u, --uptod…...

【DP】62.不同路径

题目 法1&#xff1a;二维DP 必须掌握&#xff01; class Solution {public int uniquePaths(int m, int n) {int[][] matrix new int[m][n];Arrays.fill(matrix[0], 1);for (int i 0; i < m; i) {matrix[i][0] 1;}for (int i 1; i < m; i) {for (int j 1; j <…...

大数据、知识图谱和强化学习的综合应用

大数据、知识图谱和强化学习各自在不同的方面都发挥了重要作用&#xff0c;它们分别涉及了大规模数据的处理和挖掘、基于图的数据结构和信息提取&#xff0c;以及基于奖励反馈的决策制定。将它们结合使用&#xff0c;可以构建出更加强大和智能的系统。以下是一些可能的应用场景…...

MFC使用高速绘图控件high-speed Charting Control绘制柱形图

1. 创建MFC单文档工程BarChartDemo。 2. 在工程文件夹下新建文件夹ChartCtrl,将ChartCtrl源码放入,如下图所示。在工程中添加这些项,项目——添加——现有项,全部添加。 3. 添加一个对话框,ID为IDD_DLG_BAR,类名为CBarDlg。 4. 在对话框中添加Custom Control控件,将控…...

vue3 H5项目中实现PDF预览

是需要npm i vue-pdf-embed 安装这个插件的&#xff0c;可兼容ios/Android&#xff0c;下面是本人的使用实例 <template><div class"conten_box"><vue-pdf-embed v-if"pdfSource.url" :source"pdfSource" /></div> <…...

【WebRTC---源码篇】(十一:一)采集编码发送期间使用时间戳的详细解读

一、时间戳定义 1、 NTP时间 NtpTime RealTimeClock::CurrentNtpTime() //获取从1900-01-01 00:00.00到当前时刻经过的时间 int64_t RealTimeClock::CurrentNtpInMilliseconds() //获取从1900-01-01 00:00.00到当前时刻经过的毫秒数,ms int64_t rtc::TimeUTCMicros() //获取…...

Python学习路线 - Python语言基础入门 - Python异常、模块与包

Python学习路线 - Python语言基础入门 - Python异常、模块与包 了解异常什么是异常bug单词的诞生异常演示 异常的捕获方法为什么要捕获异常捕获常规异常捕获指定异常捕获多个异常捕获异常并输出描述信息捕获所有异常异常 else异常的finally 异常的传递Python模块什么是模块模块…...

长沙有什么好玩的水上乐园/开封网站快速排名优化

安装说明 系统环境&#xff1a;centos-6.3 安装方式&#xff1a;rpm安装 软件&#xff1a;jdk-7-linux-x64.rpm 下载地址&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/java-se-jdk-7-download-432154.html 检验系统原版本 [rootadmin ~]# java -…...

做游戏ppt下载网站有哪些内容/直销的八大课程

绑定两台路由器之间的多条E1链路的方法有如下几种1.硬件IMUX 2-82.ATM IMA 2-323.Multilink ppp 2-84.Load balancing 2-6其中1、2为硬件解决方式&#xff0c;3、4为软件解决方式 PPP multilink配置方法&#xff1a;interface Mu…...

wordpress讨论吧/市场调研报告范文3000字

LP Wizard10.5破解笔记&#xff1a; 首先下载完安装包&#xff08;附破解包&#xff09;后解压会有两个文件夹&#xff0c; 1.先运行一次Crack.vbs&#xff0c;路径空着 2.点LPWizard_mib.exe安装软件&#xff0c;安装到默认路径&#xff0c;不安装license。 3.再运行一次Crack…...

wordpress swf 上传/惠州seo排名收费

什么是存储过程&#xff1a;存储过程一般用于处理比较复杂的任务&#xff0c;基础ms这个平台&#xff0c;可以大大降低耗时&#xff0c;其编译机制也提高了数据库执行速度。 当然在系统控制方便方面&#xff0c;例如当系统进行调整时&#xff0c;这是只需要将后台存储过程进行更…...

wordpress 禁止自动保存 插件/网络营销策划书封面

变量变量&#xff1a;将运算的中间结果暂存到内存中&#xff0c;以便后续程序调用。变量的命令规则&#xff1a;变量由字母、数字、下划线组合而成。不可以数字开头&#xff0c;更不能全是数字。不能是python的关键字。不要用中文。名字要有意义。不要太长。区分大小写。推荐使…...

中企动力网站建设方案/建设优化网站

有些网站图片做了防盗处理&#xff0c;这时可以通过伪造http_referer &#xff0c;让网站认为是网站内的访问之后把相应的内容保存下来&#xff01;步骤一&#xff1a;引入dll: /Files/xiachufeng/Interop.MSXML2.rar步骤二: 编写函数 /// <summary>/// 伪造http_refere…...