APK 검사: dex 에 GeneratedPluginRegistrant 가 있는지 (tool/check_apk.ps1)
묶음5 시험판 (a192ef6) 이 켜자마자 꺼졌다 ('JNI is not initialized … too early'). 생성 파일 GeneratedPluginRegistrant.java 를 지운 뒤
flutter build apk --no-pub 로 빌드해 플러그인 등록이 dex 에서 빠진 것 (버그 수정 - 빌드 절차). 빌드 뒤 이 검사로 막는다.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix_mkv
parent
e9f7e5d819
commit
3639aa9cbf
|
|
@ -0,0 +1,47 @@
|
||||||
|
# APK 검사 (P0, 10/11): 플러그인 등록 (GeneratedPluginRegistrant) 이 dex 에 들어 있는지 본다.
|
||||||
|
# - 이 파일이 빠지면 플러그인이 하나도 등록되지 않아 켜자마자 꺼진다 ('JNI is not initialized … too early', 묶음5 a192ef6 시험판).
|
||||||
|
# - 원인: android\app\src\main\java\io\flutter\plugins\GeneratedPluginRegistrant.java (git 밖, 생성 파일) 를 지운 뒤
|
||||||
|
# flutter build apk --no-pub 로 빌드하면 다시 만들어지지 않는다. 지웠으면 --no-pub 없이 빌드하거나 먼저 flutter pub get.
|
||||||
|
# 사용: powershell -ExecutionPolicy Bypass -File tool\check_apk.ps1 -Apk build\app\outputs\flutter-apk\app-release.apk
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)][string]$Apk
|
||||||
|
)
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
||||||
|
$Apk = (Resolve-Path $Apk).Path
|
||||||
|
$want = [System.Text.Encoding]::ASCII.GetBytes('Lio/flutter/plugins/GeneratedPluginRegistrant;')
|
||||||
|
|
||||||
|
# 바이트 배열 안에 [needle] 이 있는지
|
||||||
|
function Test-Bytes([byte[]]$hay, [byte[]]$needle) {
|
||||||
|
$first = $needle[0]
|
||||||
|
$i = [Array]::IndexOf($hay, $first)
|
||||||
|
while ($i -ge 0 -and $i -le $hay.Length - $needle.Length) {
|
||||||
|
$ok = $true
|
||||||
|
for ($k = 1; $k -lt $needle.Length; $k++) {
|
||||||
|
if ($hay[$i + $k] -ne $needle[$k]) { $ok = $false; break }
|
||||||
|
}
|
||||||
|
if ($ok) { return $true }
|
||||||
|
$i = [Array]::IndexOf($hay, $first, $i + 1)
|
||||||
|
}
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
|
$zip = [System.IO.Compression.ZipFile]::OpenRead($Apk)
|
||||||
|
try {
|
||||||
|
$dexes = @($zip.Entries | Where-Object { $_.FullName -match '^classes\d*\.dex$' })
|
||||||
|
if ($dexes.Count -eq 0) { throw "dex 가 없습니다: $Apk" }
|
||||||
|
$found = $null
|
||||||
|
foreach ($e in $dexes) {
|
||||||
|
$s = $e.Open()
|
||||||
|
$ms = New-Object System.IO.MemoryStream
|
||||||
|
try { $s.CopyTo($ms) } finally { $s.Dispose() }
|
||||||
|
if (Test-Bytes $ms.ToArray() $want) { $found = $e.FullName; break }
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
$zip.Dispose()
|
||||||
|
}
|
||||||
|
if (-not $found) {
|
||||||
|
Write-Host "실패: GeneratedPluginRegistrant 가 dex 에 없습니다 (켜자마자 꺼지는 APK). flutter pub get 뒤 --no-pub 없이 다시 빌드하세요." -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
Write-Host "통과: GeneratedPluginRegistrant 있음 ($found)"
|
||||||
Loading…
Reference in New Issue