English | 简体中文 | 繁體中文 | Português (BR) | Русский | 日本語
Dedicated Android launcher and mod manager for Plants Vs Zombies Fusion.
- Package:
com.LanPiaoPiao.PlantsVsZombiesRH - Unity activity:
com.unity3d.player.UnityPlayerActivity - Unity version:
2022.3.62f1c1 - ABI:
arm64-v8a - Launcher package:
com.pvzrh.android.launcher
- BepInEx — Unity IL2CPP modding framework, the core plugin loader
- FusionCore — Android Unity IL2CPP Runtime Container by Starlight team
- NextBep (BepInEx.Android) — Custom BepInEx fork for Android
- BepInEx.Android.Launcher — Generic BepInEx Android launcher with modpack management
- dotnet/runtime — .NET Runtime, built from source with OpenSSL crypto backend
- OpenSSL — OpenSSL 3.4.0, replacing BoringSSL for ARM64 Android crypto
- Pine — ART Java method hook framework
- Dobby — Native hook framework for ARM64
- Cpp2IL — IL2CPP reverse engineering tool
HayashiUme · Gaoshu · NextBep
©2026 PVZRH Mod Dev
- Contributing — How to contribute to the project
- Translate — Help translate the launcher into your language
- Troubleshooting — Common issues and fixes
There is a CI build in the GitHub Actions page.
Run from this directory:
.\gradlew.bat :app:assembleDebugThe APK is written to:
app/build/outputs/apk/debug/app-debug.apk
Each build increments ci-version.txt and sets the APK version to:
0.0.1-ci.<number>
For a clean test installation:
$adb = "E:\Android\Sdk\platform-tools\adb.exe"
$apk = "E:\WindowsFile\BepInExt\PVZRH.Android.Launcher\app\build\outputs\apk\debug\app-debug.apk"
& $adb uninstall com.pvzrh.android.launcher
& $adb install $apkUninstalling removes launcher-private data and settings. It does not remove the external PVZRH data directory.
Runtime BepInEx data is stored under:
/storage/emulated/0/PVZRH_Launcher/com.LanPiaoPiao.PlantsVsZombiesRH/
The directory contains plugins, configuration, logs, modpacks, and vanilla state.
The launcher injects BepInEx into the game process using Pine (Java method hooking framework):
createPackageContext()for PVZRH to obtain its class loader and DEX access.- Install Pine hooks: bidirectional ClassLoader, Instrumentation, PackageManager, native library, and UnityPlayer.
- Redirect the game activity to a manifest-registered
StubActivityviaInstrumentation.execStartActivityhook. Instrumentation.newActivityrestores the real game activity class and original Intent.Activity.attachBaseContexthook wraps the Context with a three-wayCustomContextWrapper:- Game resources (Assets, Resources, Theme) → PVZRH package context
- File/storage (getFilesDir, SharedPreferences) → launcher Application
- Window services (getDisplay, getSystemService) → original Activity base Context
ClassLoader.findLibrary()hook redirects native .so loading: game libs from game APK, fusion libs from launcher, .NET/il2cpp/unity libs from data directory.UnityPlayerconstructor hook sets the activity field and shows injection overlay.UnityPlayer.kill()hook blocks the first call for 5 seconds to survive integrity checks.
All hooks are installed from Kotlin/Java — no native libmain.so bootstrap required.
After a crash, the next launcher start saves diagnostics under:
/data/user/0/com.pvzrh.android.launcher/files/debug/<timestamp>/
Snapshots include launcher logs, logcat, crash logcat, package/activity state, process exit information, and available BepInEx logs.