Android之Windows下生成动态库so并打包到APK中
来源:互联网 发布:恶搞改图软件 编辑:程序博客网 时间:2024/04/29 06:41
Android内核是Linux的,而linux的动态库是*.so文件,那么在windows要如何生成并打包到APK中呢?实现这一过程,大致需要以下几个步骤:
1、搭建编译环境
2、使用JNI生成相应的头文件
3、编写动态库的实现
4、生成动态库
5、编译调用动态库的代码
6、动态库打包到APK中
7、测试
下面就依据这些步骤一一进行实现。
1、搭建编译环境
要生成*.so的动态库文件,需要有交叉编译的环境,这个可以在Linux下搭建,在windows下也同样可以。在Windows下需要借助Sourcery CodeBench Lite Edition for ARM,这个可以直接到官网上下载(可能需要注册帐号),这里是地址https://sourcery.mentor.com/sgpp/lite/arm/portal/subscription?@template=lite,进入后选择GNU/Linux,如下图。
选择Sourcery CodeBench Lite 2013.11-33,进入下面的页面。
下载完后,直接安装,按照提示一路下一步。安装的路径最好不要放在有空格或者含中文的路径下,比如默认文件夹Program Files就是带空格的,这样的路径有可能会影响命令的执行。我是安装到D:\Sourcery_CodeBench_Lite_for_ARM_GNU_Linux。
安装完成后,将安装目录下的bin设置到环境变量中,即D:\Sourcery_CodeBench_Lite_for_ARM_GNU_Linux\bin。
设置了环境变量后,才能方便调用这些exe。
2、使用JNI生成相应的头文件
(1)、在Eclipse中新建一个Android工程,命名为DynamicLibTest,名包为com.example.dlt,新建一个调用动态库的类NativeJniAdder.java,代码如下
package
com.example.dlt;
import
android.util.Log;
public
class
NativeJniAdder {
static
{
try
{
Log.i(
"JNI"
,
"Trying to load libNativeJniAdder.so"
);
System.loadLibrary(
"NativeJniAdder"
);
}
catch
(UnsatisfiedLinkError ule) {
Log.e(
"JNI"
,
"WARNING:Gould not load libNativeJniAdder.so"
);
}
}
public
static
native
int
calculate(
int
digit_1,
int
digit_2);
}
(2)、使用javah来生成头文件(javah需要安装JDK)。
在DynamicLibTest的工程下增加一个libcode文件夹,在该文件夹下添加一个生成头文件的genHeader.bat,代码如下:
javah -classpath ../src com.example.dlt.NativeJniAdder
打开该头文件会看到如下的代码:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_dlt_NativeJniAdder */
#ifndef _Included_com_example_dlt_NativeJniAdder
#define _Included_com_example_dlt_NativeJniAdder
#ifdef __cplusplus
extern
"C"
{
#endif
/*
* Class: com_example_dlt_NativeJniAdder
* Method: calculate
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_example_dlt_NativeJniAdder_calculate
(JNIEnv *, jclass, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
</jni.h>
3、编写动态库的实现
依据生成的头文件com_example_dlt_NativeJniAdder.h实现,代码如下:
com_example_dlt_NativeJniAdder.c
#include
"com_example_dlt_NativeJniAdder.h"
JNIEXPORT jint JNICALL Java_com_example_dlt_NativeJniAdder_calculate(JNIEnv *env,
jclass c, jint digit_1, jint digit_2) {
int
sum=digit_1+digit_2;
return
sum;
}
(1)、生成*.o的中间文件,编写脚本compile.bat,内容如下
arm-none-linux-gnueabi-gcc -I D:\Java\jdk7\include -I D:\Java\jdk7\include\linux -fpic -nostdlib -c com_example_dlt_NativeJniAdder.c
1)、需要安装JDK,而且JDK建立安装在无空格且不含中文的目录下,我是安装在:\Java下。执行该脚本后,将会生成com_example_dlt_NativeJniAdder.o。
2)、windows下安装jdk,在include下会有一个win32的文件夹,这里需要用到liunx的文件夹(该文件夹是在linux下安装jdk产生的),该文件夹可以从liunx下复制过来。或者建一个liunx文件夹,在下面增加jawt_md.h和jni_md.h文件,其内容如下:
jawt_md.h
/*
* %W% %E%
*
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
#ifndef _JAVASOFT_JAWT_MD_H_
#define _JAVASOFT_JAWT_MD_H_
#include <x11 xlib.h=
""
>
#include <x11 xutil.h=
""
>
#include <x11 intrinsic.h=
""
>
#include
"jawt.h"
#ifdef __cplusplus
extern
"C"
{
#endif
/*
* X11-specific declarations for AWT native interface.
* See notes in jawt.h for an example of use.
*/
typedef struct jawt_X11DrawingSurfaceInfo {
Drawable drawable;
Display* display;
VisualID visualID;
Colormap colormapID;
int
depth;
/*
* Since 1.4
* Returns a pixel value from a set of RGB values.
* This is useful for paletted color (256 color) modes.
*/
int
(JNICALL *GetAWTColor)(JAWT_DrawingSurface* ds,
int
r,
int
g,
int
b);
} JAWT_X11DrawingSurfaceInfo;
#ifdef __cplusplus
}
#endif
#endif
/* !_JAVASOFT_JAWT_MD_H_ */
</x11></x11></x11>
/*
* %W% %E%
*
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_
#define JNIEXPORT
#define JNIIMPORT
#define JNICALL
typedef
int
jint;
#ifdef _LP64
/* 64-bit Solaris */
typedef
long
jlong;
#
else
typedef
long
long
jlong;
#endif
typedef signed
char
jbyte;
#endif
/* !_JAVASOFT_JNI_MD_H_ */
(2)、检验*.o文件
cmd中定位到com_example_dlt_NativeJniAdder.o所在的目录,然后输入
arm-none-linux-gnueabi-ld com_example_dlt_NativeJniAdder.o
(3)、生成*.so的中间文件,编写脚本genSo.bat,内容如下
arm-none-linux-gnueabi-ld -T D:\Sourcery_CodeBench_Lite_for_ARM_GNU_Linux\arm-none-linux-gnueabi\lib\ldscripts\armelf_linux_eabi.xsc -shared -o ..\libs\armeabi\libNativeJniAdder.so com_example_dlt_NativeJniAdder.o
1)、D:\Sourcery_CodeBench_Lite_for_ARM_GNU_Linux是Sourcery_CodeBench_Lite_for_ARM_GNU_Linux的安装路径,需依据实际的安装路径进行修改。
2)、在DynamicLibTest工程下的libs文件夹下增加armeabi文件夹,如果libs没有,可以自行增加。
3)、生成的动态库文件的名字必须是以lib开头、以.so作为后缀的,如libNativeJniAdder.so。否则放到Android中将会识别不了。
执行脚本后,将会在armeabi文件夹下生成一个libNativeJniAdder.so的动态库文件,见下图。
5、编译调用动态库的代码
在DynamicTest工程的MainActivity.java中调用动态库。
package
com.example.dlt;
import
android.app.Activity;
import
android.os.Bundle;
import
com.example.sumcalculator.R;
public
class
MainActivity
extends
Activity {
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
int
digit_1 =
8
, digit_2 =
9
;
int
sum = NativeJniAdder.calculate(digit_1, digit_2);
setTitle(
"["
+ sum +
"]"
);
}
}
6、动态库打包到APK中
将*.so的动态库文件打包到APK中时,如果是在eclipse环境中,必须要在工程下的libs文件夹下增加一个armeabi文件夹(eabi:Embedded application binary interface, 即嵌入式应用二进制接口),然后正常编译生成apk即可。
在编译生成apk后,可以将apk解开,然后可以看到在lib文件夹下会有一个armeabi的文件夹,里面含有我们打包进去的动态库文件。
注:也可以通过adb push *.so \system\lib的方式,将*.so放到system\lib下,以供调用。但是这个过程,并不是所有手机都可以的。比如小米就不行,会被挡掉。如果使用这个命令来做,还有可能会出现only read file system的错误,这时可以先执行adb remount,然后再adb push *.so \system\lib。adb remount这个命令在小米中同样会被挡掉。
所以要怎么用,需自行斟酌。
7、测试
将apk安装到手机中,然后执行。在代码中我们执行的是8+9,所以预期的结果是[17]。测试结果如下图。
原文链接:http://www.2cto.com/kf/201403/286784.html
- Android之Windows下生成动态库so并打包到APK中
- Android之Windows下生成动态库so并打包到APK中
- Mac下使用Android的Jni生成动态库so文件,并打包到APK包说明
- 动态库so打包到android apk
- 动态库so打包到android apk
- Android 打包so动态库文件到APK
- Android 打包so动态库文件到APK
- Android 打包so动态库文件到APK
- Android 打包so动态库文件到APK
- Android 打包so动态库文件到APK
- Android 打包so动态库文件到APK
- Android Studio打包.so到apk中
- Android Studio打包.so库到apk中
- Android Studio打包.so库到apk中
- Android Studio添加so文件并打包到APK的lib文件夹中
- Android JNI以及打包so文件到apk中
- android源码中打包so到apk的方法
- android源码中打包so到apk的方法
- asterisk拨号方案的配置
- DevExpress.LookUpEdit控件实现自动搜索定位功能 兼使用方法(looUpEdit可编辑)
- mysql统计个数和插入数据
- JDBC连接MySQL数据库及示例
- HDU 3435 A new Graph Game(费用流)
- Android之Windows下生成动态库so并打包到APK中
- Top-K问题之部分划分法
- 2-2 Time类的定义
- VC 调试常用快捷键
- 使用PowerDesigner进行数据库建模入门
- QT编程实现windows的运行windows+R
- JavaScript 写的计算器
- Union和Union All的区别
- Photoshop一些人像处理技巧总结