system에 library를 embedding하고, 그것을 apk가 사용하고자 할때... (여러 apk에서 공유가능.)


Sample lib permission - com.my.lib.xml

<permissions>
    <library
        name="com.my.lib"
        file="/system/framework/com.my.lib.jar" />
</permissions>

library definition을 정의한, 위의 xml을 이용하면면, 해당 library를 system에 install하고, uses-library tag - AndroidManifest.xml - 를 이용해서 loading할 수 있게 된다.

Example uses-library

<uses-library
    android:name="com.my.lib"
    android:required="true" />

Sample Android.mk

LOCAL_PATH:= $(call my-dir)

# lib def
# -------
include $(CLEAR_VARS)
LOCAL_MODULE := com.my.lib.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
LOCAL_SRC_FILES := $(LOCAL_MODULE)
include $(BUILD_PREBUILT)

# the library
# -----------
include $(CLEAR_VARS)
LOCAL_MODULE := com.my.lib
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_SRC_FILES := $(call all-subdir-java-files)
include $(BUILD_JAVA_LIBRARY)

# the package
# -----------
include $(CLEAR_VARS)
LOCAL_MODULE := myApk
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_REQUIRED_MODULES := com.my.lib.xml com.my.lib
include $(BUILD_PREBUILT)

Explanation

* Product가 myApk 를 설치한다면, 위의 두 module 역시 설치하도록 하기 위해서 LOCAL_REQUIRED_MODULES 를 사용한다.

* Android framework은 library, feature 등을 등록하기위해서, $(TARGET_OUT_ETC)/permissions/*.xml 을 scan한다.


이렇게 하면, myApk가 load될때, uses-library 에 기록된, com.my.lib 이 같이 load된다.
단, system class loader는 여전히 BOOTCLASSPATH를 기준으로 하고 있고, Application context가 제공하는 class loader를 사용해야 위의 library가 load된 class loader를 사용할 수 있다.

다시 말하면, library에 정의된 class를 loading하기 위한 방법/예 는 아래와 같다.(class loader를 이용한 것은 example을 보여주기 위한 것 뿐, 그냥 원하는 class를 import해서 사용해도 된다. - 이미 load된 class 이므로...)

ClassLoader cloader; // cloader = new PathClassLoader("/system/framework/com.my.lib.jar", ClassLoader.getSystemClassLoader()); => (*A) // cloader = ClassLoader.getSystemClassLoader(); => (*B) // cloader = getApplicationContext().getClassLoader(); => (*C) cloader.loadClass("com.my.lib.SampleClass");


*A, *C : 정상적으로 SampleClass가 loading 됨.

*B : SampleClass를 load할 수 없음.

Done.



+ Recent posts