How to add system api classes to your android project for non AOSP builds

Viewed 2593

I have an android system app that is currently being built with the android build system. The SDK in use is system_current as it uses some system apis.

For external dependency reasons, ease of development, debugging etc, it would be nice to move this app to Android Studio and use Gradle to build.

Converting the sources to build with Gradle is straight forward enough. However, at build time, the system APIs are not found as those are not available in the normal SDK. I thought that by generating the SDK from the AOSP sources I'd get an SDK I could use, but that target output seems to also not have the System APIs available.

How would I change my gradle build to be able to use the System SDK to compile against?

3 Answers

There are two ways depending if you are only trying to use current non-public APIs, or of you've added custom ones yourselves and are trying to access those.

  • If you're only trying to use current system-level APIs, you can use android.jar from this repository https://github.com/anggrayudi/android-hidden-api

  • If you have added some new method that isn't part of standard AOSP, then it's a but more work.
    The reason that all methods don't show as part of Android SDK is that in AOSP code they are annotated with @hide. This means that when SDK is generated, they are exlcuded.
    You'll need to remove that annotation for the methods that you want to use. Then you'l need


There's also the possibility of accessing methods via reflection on runtime without SDK generation. It's slower and messier to code though.

Not sure I understand exactly what you mean by normal SDK etc.

From https://developer.android.com/studio/build

The key part is to have a

apply plugin: 'com.android.library'

...

android {
   ...
}

If on the other hand you wanted to build with a desktop JDK but compile against java APIs you could add a dependency on robolectric and you can get a jar you can import into another Android project.

implementation "org.robolectric:android-all:11-robolectric-6757853"

Android Studio isn't really designed to work with System APIs. Even if you make Gradle build your platform app, you will also need to sign it with the same certificate as your AOSP build (so that you could run it). As you noticed, if you decide to use Roboelectric you would also need to modify it yourself to match your current AOSP version (System APIs are not as stable as Public APIs and Roboelectric needs to constantly chase all the changes).

I would suggest to keep using the AOSP build system but optimize our workflow.

Ease of development

Doing a full build/flash for every change in your component must be a pain. But if you are just modifying a single app, you can get away with just building that single component:

  1. ~/aosp/ $ m -j -- do a full build first
  2. flash a clean image (with your platform certificate)
  3. ~/aosp/path/to/your/app/ $ mma -j -- build your app with all dependencies after you made changes
  4. $ adb root && adb remount && adb sync

Basically, adb sync works great if you don't touch any APIs or parts of Android Framework (which would cause a rebuild of thousands other objects). If you see adb sync updating more than handful of files, you'll likely end up with a bad system and need to do a full flash.

Debugging

While Android Studio is a to-go solution for regular apps, framework and the platform apps go with InteliJ (you can probably use Android Studio, but there won't be much of use of Android plugins on top InteliJ) plus some configuration (see idegen.sh - example).

Related