7.1 KiB
Android Compatibility Module
This module provides Android framework compatibility for running Aniyomi/Tachiyomi extensions on desktop JVM.
How It Works
This module uses a hybrid approach inspired by Suwayomi:
- Base Android SDK: Downloads the official Android SDK
android.jarfrom Sable/android-platforms - Custom Stubs: Provides desktop-specific implementations for classes that need different behavior
- Jar Patching: Removes SDK classes that have custom implementations to avoid conflicts
Architecture
androidcompat/
├── src/main/java/
│ └── android/ # Custom stub implementations
│ ├── app/ # Application, Service
│ ├── content/ # Context, SharedPreferences
│ ├── graphics/ # Bitmap, Canvas
│ ├── net/ # Uri
│ ├── os/ # Handler, Looper, Build, Environment
│ ├── webkit/ # WebView, WebSettings, WebViewClient
│ ├── widget/ # Toast
│ └── util/ # Log, Base64
├── src/main/java/
│ └── androidx/ # AndroidX compatibility
│ ├── core/ # ContextCompat
│ └── preference/ # Preference classes
├── scripts/
│ └── get-android.sh # Downloads and patches android.jar
└── pom.xml
Custom Stubs
The following classes have custom desktop implementations:
android.app
Application.java- Application lifecycle and preferencesService.java- Background service stub
android.content
Context.java- Application context with resource accessSharedPreferences.java- Preference storage interfaceSharedPreferencesImpl.java- Desktop file-based preferences
android.os
Handler.java- Message handling (synchronous on desktop)Looper.java- Message loop (simplified for desktop)Build.java- Build informationEnvironment.java- Environment paths
android.webkit
WebView.java- WebView using JavaFX WebViewWebSettings.java- WebView settingsWebViewClient.java- WebView callbacksCookieManager.java- Cookie management
android.graphics
Bitmap.java- Image handling
android.net
Uri.java- URI parsing
android.widget
Toast.java- Toast notifications (logs to console)
android.util
Log.java- Logging to stdout/stderrBase64.java- Base64 encoding/decoding
Adding New Stubs
- Identify which Android class needs a desktop implementation
- Create the class in
src/main/java/android/<package>/ - Add the class path to
scripts/get-android.shinCUSTOM_CLASSESarray - Run
mvn clean compileto rebuild with patched JAR
How to Use
The androidcompat module is automatically included as a dependency in the core module. The build process:
- Downloads official
android.jarfrom Sable/android-platforms - Removes classes that have custom implementations (to avoid conflicts with our stubs)
- Compiles custom stubs alongside the patched JAR
- Packages everything into the final JAR
IntelliJ IDEA Setup (Code Navigation)
The stripped android.jar (SDK classes minus our stubs) is added as a system dependency in pom.xml. This lets IntelliJ index it so you can navigate Android SDK source code with Ctrl+Click.
First-Time Setup
-
Download the JAR (one-time):
cd androidcompat ./scripts/get-android.shOr just run a build:
mvn clean compile -pl androidcompat -
Reload the Maven project in IntelliJ:
- Right-click
androidcompat/pom.xml→ Maven → Reload Project - Or press
Ctrl+Shift+O(Linux/Windows) /Cmd+Shift+O(Mac)
- Right-click
-
Verify it's working:
- Open
androidcompat/src/main/java/android/content/Context.java - Press
Ctrl+BonApplicationInfo(or any SDK class not in our stubs) - IntelliJ should decompile and show the SDK source
- Open
What You'll See
In the Project Structure (Ctrl+Alt+Shift+S) → Libraries, you should see:
Maven: com.google.android:android-sdk-stripped:34
└── androidcompat/target/android.jar
This JAR contains only SDK classes we haven't stubbed — so when you navigate to android.app.Activity, you see the real Android implementation, but when you navigate to android.content.Context, you see our stub.
Troubleshooting
"Library not found" or red text in pom.xml:
- The JAR hasn't been downloaded yet. Run
./scripts/get-android.shormvn clean compile.
"Cannot resolve symbol" for Android classes:
- Reload the Maven project: right-click
pom.xml→ Maven → Reload Project - Or: File → Invalidate Caches → Invalidate and Restart
Want to see our stubs instead of SDK classes?
- Our stubs are regular source files in
src/main/java/android/... - If IntelliJ shows the decompiled SDK version, it means that class is not in our stubs (which is useful info!)
- To stub it, create the class in
src/main/java/android/<package>/and add it toget-android.sh
Skipping the Download
If you already have android.jar downloaded or want to skip the download:
mvn clean package -Dexec.skip=true
Manual Download
If automatic download fails, you can manually download:
# Download from Sable/android-platforms
curl -o androidcompat/target/android.jar \
https://raw.githubusercontent.com/Sable/android-platforms/master/android-34/android.jar
# Then build
mvn clean package -Dexec.skip=true
Extending Android Support
When an extension requires an Android class that doesn't exist:
Option 1: Minimal Stub (Recommended for quick fixes)
Create a stub that throws RuntimeException for unimplemented methods:
package android.some.package;
public class SomeClass {
public void someMethod() {
throw new RuntimeException("Not implemented: SomeClass.someMethod()");
}
}
Option 2: Full Desktop Implementation
Provide a desktop-compatible implementation (e.g., using JavaFX instead of Android UI).
Option 3: Use Android SDK Class
If the class works as-is on desktop, just add it to the exclusions list in get-android.sh so it's downloaded from the SDK.
Troubleshooting
ClassNotFoundException for Android classes
- Check if the class is in the downloaded
android.jar - If not, create a stub in
src/main/java/android/... - Add the class to
CUSTOM_CLASSESinget-android.sh
MethodNotFoundError
- The Android SDK version might be too old
- Update
ANDROID_SDK_VERSIONinget-android.sh - Or create a custom stub with the required method
Class cast exceptions
- Custom stub might conflict with SDK class
- Ensure class is in
CUSTOM_CLASSESexclusion list - Run
mvn cleanto rebuild android.jar
References
- Suwayomi's AndroidCompat: https://github.com/Suwayomi/Suwayomi-Server/tree/master/AndroidCompat
- Android SDK: https://developer.android.com/reference/
- dex2jar: https://github.com/pxb1988/dex2jar