flutter2026学习笔记
在 Windows 搜索框输入“环境变量”,选择“编辑系统环境变量”。下载最新的 Stable 版本压缩包。:将压缩包解压到一个路径简单的文件夹里(命令,电脑都能认出它。:让你在任何地方输入。
1、基础环境
下载:去 Flutter 官网 下载最新的 Stable 版本压缩包。
解压:将压缩包解压到一个路径简单的文件夹里(千万不要放进
C:\Program Files,会有权限问题)。推荐路径:C:\src\flutter。配置环境变量(最关键的一步):
在 Windows 搜索框输入“环境变量”,选择“编辑系统环境变量”。
找到
Path变量,添加一条新路径:C:\src\flutter\bin。作用:让你在任何地方输入
flutter命令,电脑都能认出它。
Building flutter tool...:Flutter 正在编译它自带的命令行工具。因为你刚解压或者第一次运行,它需要把源码转换成电脑能直接执行的文件。
Running pub upgrade...:它在检查和更新 Flutter 内部依赖的组件包。
Resolving dependencies...:它在联网确认所有的配套零件是否都配齐了。
需要配置国内镜像
变量名 变量值 FLUTTER_STORAGE_BASE_URL https://storage.flutter-io.cnPUB_HOSTED_URL https://pub.flutter-io.cn
1. 核心开发工具与平台
Android SDK Platform:这是针对特定安卓版本(如截图中的 Android 36.1)的编译环境。
Android SDK Platform-Tools:包含连接手机必不可少的工具,如
adb(安卓调试桥)。Android SDK Build-Tools:用于将你的 Flutter 代码真正打包成
.apk安装包的工具。2. 模拟器相关组件
Android Emulator:在电脑上模拟手机运行的软件本体。
Google Play Intel x86_64 Atom System Image:这是模拟器的“操作系统镜像”,体积通常在 2 GB - 5 GB 之间,决定了模拟器里运行的是哪个版本的安卓系统。
Android Emulator Hypervisor Driver:这是为了让模拟器在 Windows 电脑上运行得更流畅的加速驱动。
3. 源码与文档
Sources for Android:安卓系统的源代码,方便你在开发时查看底层逻辑。
默认已经安装上了android sdk
还是不知道android sdk在哪
flutter config --android-sdk "D:\soft\androidStudio\sdk"
这里需要你同意sdk中各年份中的协议
2、开始项目
vscode中安装flutter插件
vscode新建flutter项目报找不到android sdk目录,需要添加环境变量
第一步:新建
ANDROID_HOME
在 Windows 搜索框输入“环境变量”,打开“编辑系统环境变量”。
点击“环境变量”按钮。
在下方的 系统变量 区域点击“新建”:
变量名:
ANDROID_HOME变量值:
D:\soft\androidStudio\sdk第二步:添加四个关键工具路径到
Path
在同一窗口找到 Path 变量,双击打开。
点击“新建”,分别添加以下四个路径(建议直接复制):
%ANDROID_HOME%\platform-tools(这是最常用的,包含adb命令)
%ANDROID_HOME%\cmdline-tools\latest\bin(这是你之前问到的命令行工具)
%ANDROID_HOME%\build-tools\36.1.0(注:这里的版本号要根据你D:\...\build-tools文件夹下的实际名字改)
%ANDROID_HOME%\emulator(用于命令行启动模拟器)
graph LR
Project[my_app 根目录] --- android[android/ - 安卓原生配置,平时不用管]
Project --- ios[ios/ - iOS 原生配置,Windows下打不开]
Project --- linux[linux/ - Linux 桌面版配置]
Project --- macos[macos/ - Mac 桌面版配置]
Project --- web[web/ - 网页版配置,如网站标题和图标]
Project --- windows[windows/ - Windows 桌面版配置]
Project --- lib[lib/ - 核心代码区: 你的 99% 工作都在这]
lib --- main.dart[main.dart - 程序入口: 相当于 App 的大脑]
Project --- test[test/ - 测试代码: 存放自动化测试脚本]
Project --- config[配置文件]
config --- pubspec.yaml[pubspec.yaml - 资源管家: 配置图片/插件/字体]
config --- dot_gitignore[.gitignore - 忽略文件: 哪些东西不上传到 Git]
config --- README[README.md - 项目说明书]
运行时会报Failed to update packages.
需要终端运行
$env:PUB_HOSTED_URL="https://pub.flutter-io.cn" $env:FLUTTER_STORAGE_BASE_URL="https://storage.flutter-io.cn"
启动web服务器
flutter run -d web-server --web-hostname=0.0.0.0 --web-port=8080查看可用设备
flutter devices
运行到chrome
flutter run -d chrome --web-hostname=0.0.0.0支持热更新
运行成功后,会自动打开一个chrome窗口,成功创建开发服务器和调试通道
- 开发服务器:监听
0.0.0.0:端口,提供静态资源- 调试通道:通过 WebSocket 绑定到首次打开的 Chrome 窗口(用于热重载、日志输出)
关闭首次打开的窗口将失去调试连接
web-server模式运行(无调试依赖)不支持热更新flutter run -d web-server --web-hostname=0.0.0.0 --web-port=8080
运行到android studio虚拟机
2.1 网页
启动服务
flutter run -d chrome
打包服务
flutter build web --release
2.2 安卓
用Hbuilderx无线连接红米手机也能运行
flutter run -d 2312DRA50C
成功运行
真机调试 手机开启调试模式,连接数据线
flutter run -d 68c5806c
打包调试apk
flutter build apk --debug
3、常用操作
3.1 修改应用名
安卓
D:\develop\flutter\flutter_application_1\android\app\src\main\AndroidManifest.xml
苹果
D:\develop\flutter\flutter_application_1\ios\Runner\
3.2 修改应用图标
flutter_launcher_icons: ^0.14.3 # 自动生成各平台所有尺寸的应用图标
1. 准备图标文件
- 准备一张 1024×1024 px 的 PNG 图标(不要圆角,系统会自动裁剪)
- 创建目录并放入文件:
flutter_application_1/
└── assets/
└── icons/
├── app_icon.png ← 完整图标(1024×1024)
└── app_icon_foreground.png ← 自适应图标前景(Android 8+,可以和上面用同一张)
2. 运行生成命令
项目根目录里面运行
dart run flutter_launcher_icons这条命令会自动把你的 1024×1024 图标裁剪成 Android/iOS 所需的所有尺寸:
平台 生成位置 Android 普通图标 android/app/src/main/res/mipmap-mdpi/等 5 个分辨率Android 自适应图标(8.0+) mipmap-anydpi-v26/— 前景 + 背景分层,支持圆形/方形裁剪iOS ios/Runner/Assets.xcassets/AppIcon.appiconset/内所有尺寸
pubspec.yaml文件中增加配置
flutter_launcher_icons: android: true # 覆盖 android/app/src/main/res/mipmap-* 下所有尺寸 ios: true # 覆盖 ios/Runner/Assets.xcassets/AppIcon.appiconset 下所有尺寸 remove_alpha_ios: true # App Store 要求 iOS 图标不能有透明通道 image_path: "assets/icons/app_icon.png" # 源图:1024×1024 px,无圆角(系统自动裁剪) min_sdk_android: 21 # 最低 Android 版本,21 = Android 5.0 # 自适应图标(Android 8.0+ 的圆形/方形自动裁剪效果): adaptive_icon_background: "#FF6B6B" # 主题色背景 adaptive_icon_foreground: "assets/icons/app_icon_foreground.png" # 前景图(可与 image_path 相同) web: generate: false windows: generate: false macos: generate: false
3.3 修改启动页
安装flutter_native_splash并在pubspec.yaml文件中增加配置
flutter_native_splash: # 亮色启动页 color: "#F8F8F8" # 背景色,和 App 亮色背景一致 color_dark: "#121212" # 暗色模式背景色 # image: assets/splash_logo.png # 中间图标,如有 logo 取消注释 fullscreen: false # 不全屏(保留状态栏) android_12: color: "#F8F8F8" color_dark: "#121212" # image: assets/splash_logo.png # 中间图标,如有 logo 取消注释 # 也可以设置图标背景 # icon_background_color: "#ffffff"dart run flutter_native_splash:create
3.4 生成安卓证书
签名证书(keystore)
keytool:JDK 自带的
keytool命令java -version
keytool -version
# 通用命令(建议将证书放在 Flutter 项目的 android 目录下,方便管理) keytool -genkey -v -keystore D:\develop\flutter\flutter_application_1\android\key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key
-keystore ~/key.jks:指定证书文件的保存路径和名称(~/是用户根目录,Mac/Linux 可改为./android/key.jks,Windows 可改为D:\flutter_project\android\key.jks)。-keyalg RSA:加密算法(固定用 RSA 即可)。-keysize 2048:密钥长度(行业标准,无需修改)。-validity 10000:证书有效期(10000 天,约 27 年)。-alias key:证书别名(自定义,比如你的应用名,后续配置会用到)。# 查看证书指纹 keytool -list -v -keystore D:\develop\flutter\flutter_application_1\android\key.jks -alias key -storepass 123456 -keypass 123456
别名: key 创建日期: 2026年3月11日 条目类型: PrivateKeyEntry 证书链长度: 1 证书[1]: 所有者: CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown 发布者: CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown 序列号: 68d345b67ae9712b 生效时间: Wed Mar 11 20:32:37 CST 2026, 失效时间: Sun Jul 27 20:32:37 CST 2053 证书指纹: SHA1: EF:6C:96:FD:3C:D3:07:AC:FD:0A:46:87:62:26:B6:85:E2:1C:0D:71 SHA256: 50:8E:E1:C1:A0:90:3D:4A:4C:60:1B:CF:10:09:18:A3:AF:A1:58:46:5E:8C:A9:20:D6:80:0C:47:9D:A5:68:BB 签名算法名称: SHA384withRSA 主体公共密钥算法: 2048 位 RSA 密钥 版本: 3 扩展: #1: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: D7 91 62 C9 43 C9 8C BF 01 C1 4D 76 56 F7 FF 61 ..b.C.....MvV..a 0010: 3A 6D D7 E2 :m.. ] ]
然后再android下新建key.properties文件
# 证书文件路径(因为 key.jks 在 android 目录下,直接写文件名即可) storeFile=key.jks # 解锁整个证书文件(key.jks),对应你截图中输入的第一个密码(输入密钥库口令) storePassword=123456 # 解锁文件里的具体密钥条目, 对应你生成时的第二个密码(输入 <key> 的密钥口令) keyPassword=123456 # 生成证书时的别名(你用的是 key) keyAlias=key
build.gradle.kts里面增加
import java.io.FileInputStream import java.util.Properties // 加载签名配置文件 key.properties val keystoreProperties = Properties() val keystorePropertiesFile = rootProject.file("key.properties") if (keystorePropertiesFile.exists()) { keystoreProperties.load(FileInputStream(keystorePropertiesFile)) }// 新增:签名配置(关键!) signingConfigs { create("release") { keyAlias = keystoreProperties["keyAlias"] as String keyPassword = keystoreProperties["keyPassword"] as String storeFile = file(keystoreProperties["storeFile"] as String) storePassword = keystoreProperties["storePassword"] as String } }
检查打包是否正常
真机安装测试是否有未签名
未签名时
未经过应用商店下载,无论有无签名都是这样
3.5 ICP备案
ICP 备案(APP 备案 / APP 核准):国家工信部要求的行政备案,只要你的 APP 对外提供互联网服务,就必须在工信部系统登记,否则会被国内手机系统判定为「未合规应用」
3.6 google play上架要求
一、Google Play 上架的核心要求(2026)
- 开发者账号:Google 账号 + 一次性 25 美元注册费。
- 身份认证:个人用身份证 / 护照;企业用营业执照 + 法人身份证。
- 应用合规:
- 目标 SDK ≥ 33(新提交强制)。
- 提供隐私政策链接、完成年龄分级。
- 含内购必须接入 Google Play Billing。
- 中国大陆主体可能需要出口备案号。
- 不要求:ICP 备案、APP 备案、软著、版号、公安备案。
二、与国内安卓商店的关键区别
表格
要求 Google Play 国内商店(华为 / 小米 / 应用宝等) ICP/APP 备案 ❌ 不需要 ✅ 必须 软著 ❌ 不需要 ✅ 必须 版号(游戏) ❌ 不需要 ✅ 必须 费用 25 美元一次性 免费(备案 / 审核) 审核重点 内容合规、安全、隐私 资质齐全、备案完整 三、你需要注意的边界情况
- 只上架 Google Play,不进国内商店
- 完全不用做 ICP 备案。
- 包名、签名、SHA1 只需要满足 Google Play 要求即可。
- 同时上架 Google Play + 国内商店
- 国内商店必须做 ICP/APP 备案。
- 包名、签名、SHA1 必须完全一致(否则国内商店会提示未备案)。
- 服务器在中国大陆
- 即使只上 Google Play,只要用国内服务器 / 域名,仍需做 ICP 备案(工信部对服务器 / 域名的要求)。
一、先看 2026 年个人号的核心门槛(决定难度)
1. 账号注册门槛(低)
- 费用:25 美元一次性,无年费。
- 材料:真实姓名、邮箱、手机号、支付方式(信用卡 / PayPal),不需要营业执照、ICP、软著。
- 风险:IP / 设备 / 支付卡不能与被封账号关联,否则秒封。
2. 强制封闭测试(高门槛,个人号专属)
- 规则:新个人号必须先做 20 名真实测试者连续 14 天封闭测试,才能申请正式上架权限。
- 谷歌会检测:真实设备、真实交互、留存、崩溃率、IP 分散度。
- 必死操作:买僵尸号 / 模拟器 / 同一 IP 刷测试,直接拒审 + 封号。
- 难度:中等偏上,需要你有 20 个真实海外 Google 账号(老号更好)。
3. 审核机制(AI 为主,严格)
- 机器审核:代码扫描、权限、隐私、SDK、热更、签名、包名。
- 人工抽查:内容、功能、合规、数据安全。
- 审核周期:测试 14 天 + 正式审核 1–3 天,顺利约 1 个月。
二、不同类型 App 的上架难度(2026)
1. 低难度(通过率 70%+)
- 工具类:计算器、记事本、天气、简单工具、无广告 / 无内购。
- 内容类:轻阅读、壁纸、简单工具、无敏感权限。
- 特点:无敏感权限、无广告、无内购、功能简单、隐私合规。
2. 中等难度(通过率 30%–60%)
- 带广告:AdMob、Unity Ads 等,需完整数据安全声明。
- 简单内购:会员、去广告,必须用 Google Play Billing。
- 轻度敏感权限:相机、相册、位置(仅核心功能用)。
3. 高难度(通过率 <30%,甚至 <10%)
- 金融、支付、借贷、理财、虚拟货币。
- 社交、直播、短视频、陌生人交友。
- 游戏(尤其内购多、广告多、热更)。
- 短信、通话、通讯录、文件管理、设备管理等高危权限。
- 新号 + 刷量 / 刷评 / 马甲包 / 仿冒 / 侵权。
三、个人号 vs 企业号:难度对比(2026)
表格
维度 个人开发者账号 企业开发者账号(邓白氏) 封闭测试 ✅ 强制 20 人 14 天 ❌ 一般不需要 风控等级 极高,秒封风险大 低,容错率高 权限开放 限制高危权限 完整权限开放 审核宽松度 严 松 账号寿命 短,易被连坐 长,稳定 适合 个人小工具、轻量应用 商业应用、高风险行业
四、个人开发者最容易踩的坑(直接导致失败)
- 测试造假:用模拟器、同一 IP、僵尸号刷 14 天测试。
- 隐私缺失:无隐私政策链接、数据安全表单(Data Safety)填错 / 漏填。
- 权限滥用:申请与功能无关的敏感权限(如记事本要短信)。
- 热更 / 动态代码:绕过 Google Play 下载 DEX/JAR/so,直接封号。
- 账号关联:同一设备 / IP / 支付卡注册多个账号,连坐封禁。
- 内容违规:暴力、色情、侵权、仿冒、虚假宣传。
- 支付违规:数字商品不用 Google Play Billing,直接拒审。
五、个人开发者稳过上架的实操建议(2026)
- 先做合规小应用养号
- 第一个 App 做无广告、无内购、无敏感权限的轻工具,积累账号信誉。
- 真实测试,拒绝造假
- 找 20 个真实海外 Google 老号(注册 ≥6 个月),用真实设备,每天深度交互。
- 隐私合规做到极致
- 写完整隐私政策(含第三方 SDK),放 HTTPS 链接。
- 认真填 Data Safety Form,与实际数据收集完全一致。
- 权限最小化
- 只申请核心功能必需权限,敏感权限必须在使用时动态请求。
- 技术干净
- 目标 SDK ≥33,支持 64 位,无恶意代码、无热更、无隐藏功能。
- 账号环境干净
- 独立设备、独立 IP、独立支付卡,不与任何被封账号关联。
一、必备材料清单(缺一不可)
1. 基础账号与环境
- 干净的 Gmail 账号:企业邮箱(如
dev@yourcompany.com),未绑定过被封的 Google 开发者账号。- 两步验证(2FA):必须开启,用手机号 / Authenticator 验证。
- 网络与设备:独立、稳定的海外 IP(住宅 IP 更稳),独立电脑 / 浏览器,不与被封账号关联。
2. 企业主体资质(核心)
- 营业执照(原件扫描件 / 高清照片):
- 中国大陆:营业执照(三证合一),中英文翻译件(需公证 / 翻译盖章)。
- 香港:商业登记证(BR)+ 公司注册证书(CR)。
- 其他国家:当地政府签发的公司注册文件(Certificate of Incorporation)。
- 企业信息(与执照完全一致):
- 法定名称、注册地址(精确到门牌号)、统一社会信用代码 / 注册号。
- 联系电话、邮箱(可接收验证码)。
3. 邓白氏编码(D-U-N-S Number,9 位)
- 必须:2026 年中国大陆企业注册 Google Play 企业号强制要求。
- 申请:在邓白氏中国官网免费申请,审核 5–30 天。
- 注意:编码信息(公司名、地址)必须与营业执照完全一致。
4. 法人 / 联系人身份验证
- 法人身份证 / 护照(扫描件):姓名需与营业执照法人一致。
- 联系人信息:手机号(收验证码)、邮箱,不需要在职证明。
5. 支付方式(25 美元一次性注册费)
- Visa/MasterCard 国际信用卡(支持美元扣款)。
- 或 PayPal 企业账户。
- 注意:不支持国内银联单币卡。
6. 企业官网(2026 年强要求)
- 独立域名的企业官网(HTTPS 优先)。
- 需通过 Google Search Console 验证所有权。
- 官网需包含:公司介绍、联系我们、隐私政策(如已有 App)。
7. 抽查补充材料(可能需要)
- 法人手持身份证照片(部分地区抽查)。
- 对公银行对账单、水电账单(地址证明)。
- 税务登记证、增值税号(VAT)。
二、材料准备要点(避坑)
- 信息绝对一致:营业执照、邓白氏、Google 填写的公司名 / 地址 / 法人必须一字不差。
- 文件清晰:扫描件无水印、无遮挡、四角完整,中英文翻译件需正规翻译。
- 官网真实:不能是临时页、个人博客,必须是企业官方站点。
- 支付干净:信用卡未用于被封账号,账单地址可与公司地址不同,但需真实。
三、注册流程(材料备齐后)
- 用 Gmail 登录 Google Play Console。
- 选择 Organization(组织 / 企业) 账号类型。
- 输入 D-U-N-S 编码,系统自动拉取企业信息。
- 填写企业信息、联系人信息,验证手机 / 邮箱。
- 上传营业执照、法人身份证,完成企业验证。
- 验证企业官网(Search Console)。
- 支付 25 美元注册费。
- 等待 Google 审核(1–7 天),通过后即可发布应用。
四、与个人号的关键区别
表格
项目 个人账号 企业账号 邓白氏 ❌ 不需要 ✅ 必须 封闭测试 ✅ 强制 20 人 14 天 ❌ 一般不需要 审核宽松度 严 松 风控 高(易封) 低(稳定) 适合 轻量工具 商业 / 高风险 App 一句话:企业号 = 营业执照 + 邓白氏 + 官网 + 法人身份 + 25 美元,材料齐全后通过率很高。
数字商品必须用 Google Play Billing,禁止内链 USDT
五、Google Play Billing
1. 第一步:用户购买时,Google 生成核心订单数据
用户点击 “购买第 10 集” 后,Google Play 会完成以下操作:
- 验证支付(扣钱 / 扣订阅);
- 生成唯一的
purchaseToken(订单令牌)、orderId(订单号);- 记录「用户 Google 账号 ID + 商品 ID + 购买时间 + 订单状态(已购买 / 已退款)」;
- 把这些数据同步到 Google Play 服务器,同时返回给你的 App 客户端。
2. 第二步:你通过 API 读取 “用户 - 商品” 关联数据
Play Console 本身是 “数据展示后台”,它的数据来源是 Google Play Developer API,你需要主动调用 API 读取用户的购买记录:
(1)客户端查询(快速校验,适合前端展示)
Flutter/Android 端可以直接调用 Billing API,查询当前登录用户已购买的所有商品 ID,就能知道用户买了哪集 / 哪部:
import 'package:in_app_purchase/in_app_purchase.dart'; // 查询当前用户已购买的所有短剧(非消耗型商品) Future<void> checkUserPurchasedEpisodes() async { // 1. 恢复购买(关键:用户重装App/换设备后,恢复已购内容) final QueryPurchaseDetailsResponse response = await InAppPurchase.instance.queryPastPurchases(); // 2. 遍历已购商品,匹配短剧集数 for (PurchaseDetails purchase in response.pastPurchases) { if (purchase.status == PurchaseStatus.purchased) { // 3. 根据商品ID判断用户买了哪集 if (purchase.productID == 'kuangbiao_ep10') { print('用户已购买《狂飙》第10集'); // 前端解锁该集内容 unlockEpisode('kuangbiao', 10); } else if (purchase.productID == 'drama_vip_monthly') { print('用户是月度会员,解锁所有剧集'); unlockAllEpisodes(); } } } }为了避免用户篡改客户端数据(比如破解本地存储假装已购买),你必须在服务端调用 Google Play Developer API,读取用户的购买记录:
步骤:
- 在 Play Console → 「设置」→「开发者账号」→「服务账号」,创建服务账号并下载 JSON 密钥文件(替代 API Key);
- 服务端(如 Node.js/Java)用该密钥调用
purchases.products.get接口,传入「包名 + 商品 ID + 用户购买时的 purchaseToken」,校验并获取购买状态:// Node.js 示例:校验用户是否购买了《狂飙》第10集 const { google } = require('googleapis'); const auth = new google.auth.GoogleAuth({ keyFile: '你的服务账号.json', // 从 Play Console 下载 scopes: ['https://www.googleapis.com/auth/androidpublisher'] }); async function checkPurchaseStatus(packageName, productId, purchaseToken) { const androidpublisher = google.androidpublisher({ version: 'v3', auth }); // 调用 Google API 查询订单 const result = await androidpublisher.purchases.products.get({ packageName: packageName, // 你的App包名,如 com.example.shortdrama productId: productId, // 短剧商品ID,如 kuangbiao_ep10 token: purchaseToken // 用户购买时返回的 purchaseToken }); // 解析结果:判断是否已购买、是否退款 if (result.data.purchaseState === 0) { // 0=已购买,1=已取消,2=已退款 console.log('用户已购买该集短剧'); return true; } else { console.log('用户未购买/已退款'); return false; } } // 调用示例:校验用户是否买了《狂飙》第10集 checkPurchaseStatus( 'com.example.shortdrama', 'kuangbiao_ep10', '用户的purchaseToken' // 从客户端传过来 );3. 第三步:Play Console 后台查看汇总数据
你不需要手动查每个用户的购买记录,Play Console 会自动汇总所有订单数据,在「Monetization」→「Sales reports」里展示:
- 按商品 ID 统计:每集 / 每部短剧的购买量、收入;
- 按用户统计:(需自己导出数据)下载订单明细,包含「用户 ID(匿名)+ 商品 ID + 购买时间」;
- 退款 / 取消订单:自动标记,你可以在后台看到哪些用户退款了,前端 / 服务端同步取消该集解锁。
购买单集
① 用户在你 App 里登录
→ 你知道他是:
uid=123456② 用户点击购买第 10 集
→ 你调用 Google Billing→ Google 弹出支付(用他的 Google 账号付款)
③ 支付成功
Google 返回给你 3 个核心字段:
- productId:drama_01_ep10(买了哪一集)
- purchaseToken:xxxyyyzzz(Google 唯一订单号)
- orderId:GPA-xxx-xxx(谷歌订单号)
④ 你把这三个东西发给你的后端
plaintext
uid=123456 productId=drama_01_ep10 purchaseToken=xxxyyyzzz⑤ 你的后端保存:
plaintext
uid:123456 已购买 drama_01_ep10⑥ 后端再调用 Google API 验证这个 token 是真的
→ 验证通过 → 解锁内容
购买多集
① 用户登录 →
uid=123456② 用户点击「购买第 1-20 集合集」→ 你调用 Google Billing,发起「合集商品 ID」的购买请求→ Google 弹出支付(合集总价,比如 $20),用户付款
③ 支付成功Google 返回 1 组核心字段(1 个合集 ID 对应所有集):
productId:drama_01_ep1_20(自定义的合集ID) purchaseToken:token_1_20 orderId:GPA-xxx-1_20④ 你把「用户 ID + 合集商品 ID + purchaseToken」发给后端:
uid=123456 productId=drama_01_ep1_20 purchaseToken=token_1_20⑤ 你的后端先保存合集购买记录,再批量绑定该合集对应的所有集数:
# 先记录合集购买 uid:123456 已购买 drama_01_ep1_20 # 再批量解锁对应集数(后端预定义合集与集数的映射关系) uid:123456 已购买 drama_01_ep1 uid:123456 已购买 drama_01_ep2 ... uid:123456 已购买 drama_01_ep20⑥ 后端调用 Google API 验证合集商品的 purchaseToken→ 验证通过 → 解锁第 1-20 集所有内容
缺点:麻烦,需要后台配置太多商品
解决:金币充值方式
4 其它
4.1 公钥
第一步:打包 APK 时的签名(只用私钥)
- 你在 HBuilderX/Android Studio 点击「打包」,选择
key.jks签名文件并输入密码;- 系统会先对 APK 的所有代码 / 资源做一次哈希运算(生成一个唯一的 “文件摘要”);
- 用
key.jks里的私钥对这个 “文件摘要” 进行加密 → 生成「数字签名」;- 系统把「数字签名 + 公钥证书」一起打包到 APK 的 META-INF 文件夹里;
- 最终生成带签名的 APK(全程只用到私钥,公钥只是 “附带打包”)。
第二步:Google / 手机验签(只用公钥)
- 当 Google/Android 系统拿到你的 APK 时,会先提取里面的「公钥证书」和「数字签名」;
- 用同样的哈希算法,重新计算 APK 的 “文件摘要”;
- 用 APK 里的公钥解密「数字签名」→ 得到你打包时生成的原始 “文件摘要”;
- 对比 “重新计算的摘要” 和 “解密得到的摘要”:
- 一致 → 证明 APK 没被篡改,且是你用私钥签的(正版);
- 不一致 → 证明 APK 被改了 / 不是你签的(盗版)。
关键结论
表格
环节 用什么密钥 核心作用 打包签名 私钥 生成唯一的数字签名,证明 “是我签的” Google / 验签 公钥 验证签名合法性,证明 “没被篡改”
5、flutter相关
5.1 widget生命周期
class MyScreen extends StatefulWidget { @override State<MyScreen> createState() => _MyScreenState(); } class _MyScreenState extends State<MyScreen> { @override void initState() { super.initState(); // 只在页面创建时调用一次 print('initState'); } @override void didChangeDependencies() { super.didChangeDependencies(); // 依赖变化时调用 print('didChangeDependencies'); } @override Widget build(BuildContext context) { // 每次需要重建时调用 print('build'); return Container(); } @override void didUpdateWidget(MyScreen oldWidget) { super.didUpdateWidget(oldWidget); // Widget 更新时调用 print('didUpdateWidget'); } @override void deactivate() { super.deactivate(); // 页面从树中移除时调用 print('deactivate'); } @override void dispose() { super.dispose(); // 页面销毁时调用 print('dispose'); } }
更多推荐


























































所有评论(0)