Skip to content

Shizuku with Xamarin Developer Guide

neobenedict edited this page Feb 19, 2024 · 5 revisions

Shizuku + Xamarin Developer Guide

  1. Clone https://github.com/RikkaApps/Shizuku-API into Android Studio and configure your workspace until you can compile everything
  2. Build .aars for the aidl, api, provider and shared modules - gradle tab on the right - click the project - other - "buildDebugAar" for debug and "assembleRelease" for release .aars
  3. Pull these into 4 different Android Bindings Library (Xamarin) - yes they have to be 4 different ones - set .aar file Build Action to LibraryProjectZip
  4. Create new android module in Android Studio.
  5. Create .aidl and service to implement .aidl (see https://github.com/rayshift/nextgenfs as an example)
  6. Export to .aar
  7. Make a 5th binding library with this new .aar
  8. Implement a singleton (static in MainActivity works) connection handler class such as https://github.com/rayshift/translatefgo/blob/shizuku-beta/RayshiftTranslateFGO.Android/NextGenFSServiceConnection.cs
  9. Implement shizuku permission requesting (see translatefgo app e.g. https://github.com/rayshift/translatefgo/blob/shizuku-beta/RayshiftTranslateFGO.Android/MainActivity.cs#L273)
  10. Have shizuku bind (https://github.com/rayshift/translatefgo/blob/shizuku-beta/RayshiftTranslateFGO.Android/Services/IntentService.cs#L178)
  11. Done

Notes:

  • You can't pass large amounts of data over the aidl bus - you will get parcelling errors because every app seems to share a 1MB bus, it's really stupid. It doesn't even help if you do things in chunks, because the bus takes a while to clear/GC, so you gotta pause for an unknown amount of time.
  • So for anything bigger than a few kb make a temporary file in your GetExternalCacheDirs() and use System.IO copy and Java.IO copy to move data (the adb process / uid 2000 can access all external cache dirs).
  • Due to this bug https://github.com/xamarin/xamarin-android/issues/3378 you cannot write the privileged code in C#/Xamarin, it has to be written in Java (but it can be a simple wrapper to Java functions).
  • Java Exceptions cannot be caught in C# across the AIDL bus although they will show up in logcat
  • Recompiling the .aar files seems to be hit and miss if Android Studio actually detects changes - clean and rebuild always
  • You can write the binder in C# or Java, I have chosen C#
  • You must wait a little while for the binding to take place after requesting it, if you immediately try accessing the binder object it'll be null and you'll crash. Always check for null.
  • If you're passing lots of data anyway use locks so they don't happen concurrently and you run out of parcel space

I hope to never again have to deal with this.

Clone this wiki locally