Issue
I am trying to develop an android application by using some native libraries.However, the system shared libraries on android 4.0 and android 4.1.2 are different. To ensure the compatibility, I get the libskia.so file from platform 4.0, and import it into my project. I wish to load this shared library just like using a 3rd party shared library. Unfortunately, while running on android 4.1.2, my application seems still call the system skia library. I have no idea about this and the followings are my Android.mk file
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := sample
LOCAL_SRC_FILES := sample-jni.cpp
LOCAL_CFLAGS := -I /home/WORKING_DIRECTORY/external/skia/include \
-I /home/WORKING_DIRECTORY/external/skia/include/core \
-I /home/WORKING_DIRECTORY/frameworks/base/core/jni/android/graphics \
-I /home/WORKING_DIRECTORY/frameworks/base/include \
-I /home/WORKING_DIRECTORY/frameworks/base/native/include/android \
-I /home/WORKING_DIRECTORY/system/core/include \
-I /home/WORKING_DIRECTORY/external/skia/include/xml \
-I /home/WORKING_DIRECTORY/external/skia/include/images \
-I /home/WORKING_DIRECTORY/external/skia/include/views \
LOCAL_SHARED_LIBRARIES :=skia jnigraphics
include $(BUILD_SHARED_LIBRARY)
include $(LOCAL_PATH)/prebuilt/Android.mk
and the prebuilt makefile
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := skia
LOCAL_SRC_FILES := libskia.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := jnigraphics
LOCAL_SRC_FILES := libjnigraphics.so
include $(PREBUILT_SHARED_LIBRARY)
Any ideas? Or, are there any other methods to ensure compatibility?
Solution
I hope you understand that it is not recommended to have any dependencies on the system libraries beyond the stable API. But the open nature of Android allows (both technically and in terms of licensing) to introduce such dependencies. Essentially it means sailing in the non-chartered waters, and being prepared to API changes not only in the next version of the platform, but also in a vendor-provided (i.e. non-AOSP) setups of the same platform level.
Theoretically, you can put a copy of your variation of a system lib into the libs/armeabi-v7a folder of your app, and load it with System.load(fullPath) instead of loadLibrary().
But in practice I believe that system/lib/libskia.so will be loaded in your process before you have a chance to execute your code, and you cannot load two version of the same lib in the same process. Also, an older version of libskia will most likely fail to load on the system because it depends on other system libraries.
The safest way to ensure forward (and vendor) compatibility is to use dynamic linking for the undocumented system features, and perform careful error checking on the way.
But in many cases, the system undocumented APIs are actually quite stable, and the nice people in the Android team of Google do not make breaking changes too often. Therefore, if you link against the 4.0 version of skia your code will most likely simply work on 4.1.2 and on...
Update: In your particular case, when an extra field fTextLocale was added to an old class, you should first of all bless the developers who did not insert this field in the middle of the class declaration. Because now you have a reasonable strategy: use the 4.1.2 headers (with the extra field), link against the 4.0 library (that does not introduce the accessor methods to the new field), and your code will hopefully just work.
Answered By - Alex Cohn
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.