Adding an existing library or jarfile to an Android application is easy enough, but what if you wish to add it into the frameworks themselves? This post covers how to do so with an existing jarfile, though it’s also very easy to do so with the source code of the library.
Adding Files to Prebuilt
So you’ve downloaded or built the library into a jar file, which we’ll call mylib.jar
. Copy this jar file into the Android prebuilts directory, somewhere such as [android]/prebuilts/misc/common/mylib/
, in which [android]
is the top-level directory of the Android source code, like AOSP or Cyanogenmod.
In that same directory, create a makefile called Android.mk
(it must be called exactly that) with the following contents:
$ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := mylib LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := mylib.jar LOCAL_MODULE_CLASS := JAVA_LIBRARIES LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX) include $(BUILD_PREBUILT)
You can specify any name you wish for LOCAL_MODULE
, but ensure that LOCAL_SRC_FILES
specifies your jar file exactly as it is named.
Now, to build that new file, go to the top-level Android source directory and run make prebuilts
, which should setup your library properly. Or, navigate to the directory where you added the library and run mm
. The output of the build should include one “Install:” line per library that you added.
Adding additional libraries in the same directory
Android.mk
makefile. Just add the other library as such:$ LOCAL_PATH := $(call my-dir) ## for mylib include $(CLEAR_VARS) LOCAL_MODULE := mylib LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := mylib.jar LOCAL_MODULE_CLASS := JAVA_LIBRARIES LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX) include $(BUILD_PREBUILT) ## for anotherlib include $(CLEAR_VARS) LOCAL_MODULE := anotherlib LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := anotherlib.jar LOCAL_MODULE_CLASS := JAVA_LIBRARIES LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX) include $(BUILD_PREBUILT)
Using the Library in the Android Frameworks
Now that we have the library properly setup and built, we can use it by including it as a static library in the makefile of any other Android module. For example, if we wanted to use it in a system service like the AlarmManagerService
or any other code in the frameworks/base
project, we can add it to the makefile [android]/frameworks/base/Android.mk
after the LOCAL_JAVA_LIBRARIES
variable is set. Taking Android M 6.0.1 as an example, we should insert the LOCAL_STATIC_JAVA_LIBRARIES in Line 427 of the framework base’s Android.mk file.
... LOCAL_NO_STANDARD_LIBRARIES := true LOCAL_JAVA_LIBRARIES := core-libart conscrypt okhttp core-junit bouncycastle ext LOCAL_STATIC_JAVA_LIBRARIES += mylib anotherlib ### add this line LOCAL_MODULE := framework ...
Don’t forget that after you have built all of Android once using brunch
, you can quickly rebuild all system services, which go into the services.jar
file in the system partition. This is necessary if you imported and used code from the mylib
library in a system service.
cd [android] mmm frameworks/base/services
Now push the rebuilt services file to the device. Only the adb push
command actually moves the service jar to the device, the first few lines are for configuring the system partition to allow us to write a new jar file to it.
adb root adb wait-for-device adb shell mount -o rw,remount /system adb push [android]/out/target/product/hammerhead/system/framework/services.jar /system/framework/services.jar adb reboot
After the reboot, your new service or framework code that uses the new library will be running. If you don’t have a jar file compiled already and you want to add a new external library from source, you should place it in [android]/external
with a similar makefile.
I tried adding a library using the described way, but I get the following error while running mm:
FAILED: out/target/product/hikey960/obj/JAVA_LIBRARIES/testlib_intermediates/oat/arm64/testlib.odex
…
No dex files in zip file ‘/system/framework/testlib.jar’: Entry not found
Any ideas on that? I have built the testlib.jar using Android Studio and it only contains a single class with one static function.
You should use dx.bat, which is in SDK_PATH/build_tools/VERSION/ folder, to convert standard jar file to dex jar file.
You can search android dexopt to get more informartion.
LOCAL_DEX_PREOPT := false