6.9 KiB
AGENTS.md
Java/Kotlin Maven multi-module project that provides a JVM runtime for Aniyomi (anime/manga streaming) Android extensions on desktop.
Quick Commands
# Build fat JAR (includes all dependencies)
mvn clean package
# Output: aniyomi-bridge/target/aniyomiBridge-1.0.0.jar
# Main class: dev.k3vinb5.unyo.core.cli.Main
Project Structure
This is a multi-module Maven project with the following modules:
unyo-core/
├── pom.xml # Parent POM
├── androidcompat/ # Android compatibility layer
│ ├── src/main/java/android/ # Custom Android stub implementations
│ ├── src/main/java/androidx/ # AndroidX stub implementations
│ ├── scripts/get-android.sh # Android SDK JAR download script
│ └── pom.xml
├── aniyomi-bridge/ # Core bridge module
│ ├── src/main/java/ # Java sources (bridge core)
│ ├── src/main/kotlin/ # Kotlin sources (Tachiyomi/Aniyomi interfaces)
│ └── pom.xml
└── assets/ # JavaScript files for extractors
Architecture
Purpose: Bridge to load and execute Aniyomi/Tachiyomi Android extensions on desktop JVM.
Module: androidcompat
Android compatibility layer that provides Android framework classes on desktop JVM.
Approach: Hybrid (inspired by Suwayomi)
- Downloads official Android SDK
android.jaras base (optional, see below) - Provides custom stub implementations for classes that need desktop-specific behavior
- Patches JAR to remove classes with custom implementations (prevents conflicts)
Key Classes:
android.app.Application- Application singleton with preferencesandroid.content.Context- Application contextandroid.content.SharedPreferences- Preference storageandroid.os.Handler/Looper- Message handlingandroid.webkit.WebView- WebView using HtmlUnitandroid.graphics.Bitmap- Image handlingandroid.net.Uri- URI parsing
Adding New Stubs:
- Create class in
androidcompat/src/main/java/android/<package>/ - Add class pattern to
scripts/get-android.shCUSTOM_CLASSESarray - Rebuild to patch the Android SDK JAR
Android SDK Setup:
The get-android.sh script can download and patch the Android SDK JAR. Currently disabled by default.
To enable:
- Update
androidcompat/pom.xml- change<phase>none</phase>to<phase>generate-resources</phase> - Or manually download
android.jarand place inandroidcompat/target/
Module: aniyomi-bridge
Core bridge module that loads and executes extensions.
Key Classes:
AniyomiBridge.java- Main API for loading/unloading extensionsExtensionLoader.java- Loads extension classes from JAR filesApkUtils.java- Converts Android APK → JAR using dex2jar
Extension Loading Flow:
- Download APK from URL
ApkUtils.dex2jar()converts APK → JARExtensionLoader.loadClassFromJar()loads the main extension class- Cast to
AnimeHttpSourceorCatalogueSource - Store in
animeSources/mangaSourcesmaps
Build Details
- Java Version: 17 (source and target)
- Kotlin Version: 2.3.20
- Build Tool: Maven (multi-module)
- Packaging: Shade plugin creates minimized fat JAR
Maven Shade Configuration:
- Excludes signing artifacts (SF/DSA/RSA) and module-info
- Excludes
Main.classfrom the JAR (consumed by external Flutter app) - Manifest points to
dev.k3vinb5.unyo.core.cli.Main
Key Dependencies
androidcompat
kotlin-stdlib-jdk8- Kotlin standard librarykotlinx-coroutines-core- Kotlin coroutineshtmlunit- WebView implementationjsoup- HTML parsingquickjs-kt-jvm- JavaScript execution
aniyomi-bridge
androidcompat- Android compatibility layer (this project)dex2jar- Converts Android APK DEX → JARkotlinx-serialization-json- JSON handlingokhttp+okhttp-dnsoverhttps- HTTP clientbyte-buddy- Runtime bytecode patchingquickjs-kt-jvm- JavaScript execution
Development Scripts
| Script | Purpose |
|---|---|
generate-new-core-linux.sh |
Build + copy JAR to Flutter app assets (Linux path) |
generate-new-core-mac.sh |
Build + copy JAR to Flutter app assets (Mac path) |
androidcompat/scripts/get-android.sh |
Download and patch Android SDK JAR |
Both build scripts copy to a sibling project unyo-lib/assets/.
Android Stubs Strategy
Before (Single Module)
All Android stubs were manually created in the core module, leading to:
- Incomplete API coverage
- Manual stub creation for every Android class
- Maintenance burden when extensions use new Android APIs
After (Multi-Module with Hybrid Approach)
- Base SDK: Can use official Android SDK
android.jaras foundation - Custom Overrides: Only implement classes that need desktop-specific behavior
- Complete API: Access to full Android API without manual stub creation
- Maintainable: Easy to update when Android extensions evolve
Custom Stubs Location: androidcompat/src/main/java/android/
Current Custom Stubs:
android.app.Application- Application singletonandroid.content.Context- Application contextandroid.content.SharedPreferences- Preferences interfaceandroid.content.SharedPreferencesImpl- File-based preferencesandroid.os.Handler- Message handler (synchronous on desktop)android.os.Looper- Message loopandroid.webkit.WebView- HtmlUnit-based WebViewandroid.widget.Toast- Toast notifications (logs to console)android.util.Log- Logging to stdout/stderr- And more...
Extension Compatibility
The project now uses a hybrid stub approach similar to Suwayomi:
- Minimal Custom Stubs: Only stub classes that need desktop-specific implementations
- SDK Classes: Most Android classes work as-is from the SDK
- Easy Extension: Add new stubs by:
- Creating the stub class
- Adding to
CUSTOM_CLASSESinget-android.sh - Rebuilding
This approach dramatically reduces the maintenance burden and improves extension compatibility.
Repositories
Configured in parent pom.xml:
- Maven Central
- Local:
file:///${project.basedir}/libs(optional local dependencies) - Google Maven
- JitPack (for dex2jar)
Compiler Flags
Kotlin compiler args include -Xcontext-parameters (experimental feature).
Migration Notes
If you're migrating from the old single-module structure:
- Android stubs moved from
src/main/java/android/toandroidcompat/src/main/java/android/ - Build command unchanged:
mvn clean package - Output location unchanged:
aniyomi-bridge/target/ - New dependency: Core module now depends on
androidcompatmodule
Future Improvements
- Enable automatic Android SDK JAR download
- Add more complete Context implementation
- Implement additional WebView functionality
- Add comprehensive Android stub documentation
- Create stub generation utilities