FROM:http://blog.csdn.net/itluochen/article/details/53784830
常用有两种方法:
1、在windows/Linux下,首先把so动态库文件 编译出来(通过NDK),然后再 拷贝到Android的工程里 libs/armeabi/下,如果libs/armeabi 不存在,那就自己创建,最后用eclipse编译本项目,这样将自动把so文件打包到apk里;eclipse在打包的时候会根据文件名的命名规则(lib****.so)去打包so文件,开头和结尾必须分别为“lib”和“.so”,否则是不会打包到apk文件中的。
2、在android源码里,使用mm命令编译apk工程。
在project根目录下创建一个Android.mk,文件内容如:
- LOCAL_PATH:= $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_MODULE_TAGS := user
- LOCAL_SRC_FILES := $(call all-subdir-java-files)
- LOCAL_PACKAGE_NAME := jnisample
- LOCAL_JNI_SHARED_LIBRARIES := libtest
- include $(BUILD_PACKAGE)
- include $(LOCAL_PATH)/jni/Android.mk
- #include $(call all-makefiles-under,$(LOCAL_PATH))
LOCAL_JNI_SHARED_LIBRARIES := libtest 就是把so文件放到apk文件里的libs/armeabi里,而include $(LOCAL_PATH)/jni/Android.mk为了编译so文件。
把工程文件放到SDK platform/packages/apps目录下,然后进入该目录,命令里输入mm,进行该工程的编译,这样编译出来的apk,在libs/armeabi文件夹里面包含so文件。
如何把so文件打包到apk中呢?
http://blog.csdn.net/koko7958/article/details/7955046 (在这个网址里搜索:LOCAL_JNI_SHARED_LIBRARIES ,这个参数非常重要)
===》LOCAL_REQUIRED_MODULES
要注意一下这个参数:Android原生浏览器也有这行,后面的网址有解释。
LOCAL_REQUIRED_MODULES := SoundRecorder
http://blog.chinaunix.net/uid-29535415-id-4144835.html
Gallery和Camera共用了一个Android.mk文件
LOCAL_SRC_FILES是指定java文件,LOCAL_RESOURCE_DIR是指定资源文件,然后通过include $(BUILD_PACKAGE)来编译apk,其中LOCAL_REQUIRED_MODULES指定了libjni_mosaic,所以会优先编译Camera的这个c库。
include $(call all-makefiles-under, jni)
是编译Gallery的jni
剩下的就是编译测试apk
34 # Use the following include to make gallery test apk.
35 include $(call all-makefiles-under, $(LOCAL_PATH))
36
37 # Use the following include to make camera test apk.
38 include $(call all-makefiles-under, ../Camera)
别的没什么了,比较简单
===》
# additionally, build tests in sub-folders in a separate .apk
include $(call all-makefiles-under,$(LOCAL_PATH))
adding: lib/armeabi-v7a/ (stored 0%)
adding: lib/armeabi-v7a/libpatcher_jni.so (deflated 47%)
问:编译时候生成多个.so文件,有时会在armeabi和armeabi-v7a中分别放置一份,为什么?
答:该设置一般能在jni下的Application.mk中或Android.mk中找到。这个需要看你的Native Code要做什么事情,armeabi是指的该so库用于Arm的通用CPU,而v7a的CPU支持硬件浮点运算。因此armeabi通用性强,但速度慢,而v7a能充分发挥v7a CPU的能力。具体v7a的优势可以参见http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344c/Cacciced.html
介绍
http://www.myexception.cn/android/1594360.html
问题:写了个测试的android JNI app,.so已经放到了libs\armeabi下 而且从编译的apk里也能看到.so已经打包进去(解压apk文件,里边应该有lib文件夹) 但是在/data/data/com.test.test/lib下就是没有相应的.so文件
解决方法:原来是因为我的.so没有按照android标准命名,.so的名字必须有'lib'前缀 否则apk解压/安装到手机的时候不会把libs\armeabi下的.so拷贝到/data/data/com.test.test/lib下。原来我用的so名字是JNITest.so, 改为libJNITest.so后一切正常。
补充:
a) 用loadLibrary调用的时候需要去掉lib前缀 System.loadLibrary("JNITest");
b) 用load调用的时候需要写全路径名 且不能去掉lib前缀 因为这里是当成一个普通文件读取的 System.load("/data/data/com.test.test/libJNITest.so"); 其实这个是错误的,因为正规的使用根本不是引用在data/data/com.xxx/lib下的这个so文件,而是引用在libs/armeabi下的so文件,只用通过System.load("JNITest.so"); 调用即可。当然这样调用也是可以的~只不过不规范,不推荐
LOCAL_JNI_SHARED_LIBRARIES := libuserbookpatcher_jni
LOCAL_JNI_SHARED_LIBRARIES := libuserbookpatcher_jni
Install: out/target/product/xxx/system/lib/libxxxbook_jni.so
W/dalvikvm( 5177): threadid=12: thread exiting with uncaught exception (group=0x41566930)
E/AndroidRuntime( 5177): FATAL EXCEPTION: AsyncTask #3
E/AndroidRuntime( 5177): java.lang.RuntimeException: An error occured while executing doInBackground()
E/AndroidRuntime( 5177): at android.os.AsyncTask$3.done(AsyncTask.java:299)
E/AndroidRuntime( 5177): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
E/AndroidRuntime( 5177): at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
E/AndroidRuntime( 5177): at java.util.concurrent.FutureTask.run(FutureTask.java:239)
E/AndroidRuntime( 5177): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
E/AndroidRuntime( 5177): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
E/AndroidRuntime( 5177): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
E/AndroidRuntime( 5177): at java.lang.Thread.run(Thread.java:856)
E/AndroidRuntime( 5177): Caused by: java.lang.ExceptionInInitializerError
E/AndroidRuntime( 5177): at com.xxx.util.UserbookUpdateManager.update(UserbookUpdateManager.java:394)
E/AndroidRuntime( 5177): at com.xxx.util.UserbookUpdateManager.doUpgrade(UserbookUpdateManager.java:283)
E/AndroidRuntime( 5177): at com.xxx.util.UserbookUpdate.update(UserbookUpdate.java:104)
E/AndroidRuntime( 5177): at com.xxx.util.UserbookUpdate.access$000(UserbookUpdate.java:15)
E/AndroidRuntime( 5177): at com.xxx.util.UserbookUpdate$1.doInBackground(UserbookUpdate.java:57)
E/AndroidRuntime( 5177): at com.xxx.util.UserbookUpdate$1.doInBackground(UserbookUpdate.java:54)
E/AndroidRuntime( 5177): at android.os.AsyncTask$2.call(AsyncTask.java:287)
E/AndroidRuntime( 5177): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
E/AndroidRuntime( 5177): ... 4 more
E/AndroidRuntime( 5177): Caused by: java.lang.UnsatisfiedLinkError: Couldn't load xxxbook_jni from loader dalvik.system.PathClassLoader[dexPath=/system/app/xxxbook.apk,libraryPath=/data/app-lib/xxxbook]: findLibrary returned null
E/AndroidRuntime( 5177): at java.lang.Runtime.loadLibrary(Runtime.java:365)
E/AndroidRuntime( 5177): at java.lang.System.loadLibrary(System.java:535)
E/AndroidRuntime( 5177): at com.xxx.util.Patcher.<clinit>(Patcher.java:32)
E/AndroidRuntime( 5177): ... 12 more
W/ActivityManager( 1171): Force finishing activity com.xxx/.ListActivity
V/PhoneStatusBar( 2411): setLightsOn(true)
I/RenderThread( 4536): RenderThread resumed
drwxrwx--x u0_a60 u0_a60 2014-03-26 09:38 app_cache
drwxrwx--x u0_a60 u0_a60 2014-03-26 09:38 app_database
drwxrwx--x u0_a60 u0_a60 2014-03-26 09:38 cache
drwxrwx--x u0_a60 u0_a60 2014-03-26 09:38 databases
lrwxrwxrwx install install 2014-03-26 10:54 lib -> /data/app-lib/com.xxx.book-1
drwxrwx--x u0_a60 u0_a60 2014-03-26 09:38 shared_prefs