android studio 发布SDK机制实现
本文主要是Android JNI编程相关,包括java接口打包jar包,c++编译so库,通过jni调用。并在一个全新的android项目中测试使用我们自己发布的sdk的整套流程。
写这篇文章的主要目的是,网上好像并没有这么一整套的机制实现参考。
另外,完整的例子代码,见文章最后的链接。
一、制作SDK jar包so库
1.新建一个Android library
2.配置build。gradle
添加:
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.3.0' } task makeJar(type: Copy) { delete 'build/libs/mysdk.jar' from('build/intermediates/bundles/release/') into('build/libs/') include('classes.jar') rename('classes.jar', 'mysdk.jar') } makeJar.dependsOn(build)
sourceSets { main() { jniLibs.srcDirs = ['libs'] }
完整如下:
apply plugin: 'com.android.library' android { compileSdkVersion 23 buildToolsVersion '23.0.3' defaultConfig { minSdkVersion 18 targetSdkVersion 23 versionCode 1 versionName "1.0" ndk { moduleName "mylibrary" } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } sourceSets { main() { jniLibs.srcDirs = ['libs'] } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.3.0' } task makeJar(type: Copy) { delete 'build/libs/mysdk.jar' from('build/intermediates/bundles/release/') into('build/libs/') include('classes.jar') rename('classes.jar', 'mysdk.jar') } makeJar.dependsOn(build)3.新建so的java接口文件
我这里单独写了一个java类写native方法,这样做到逻辑清晰,不是和大部分网上的例子写在main里面。再就是javah生成头文件的相关网上有大量文章,我这做简述。
package com.example.mylibrary; /** * Created by Administrator on 2016/4/29. */ public class JNIInterface { public JNIInterface(){ } public native String toTestJNI(); public native String toTestJNI2(); static { System.loadLibrary("mylibrary"); } }
然后build整个项目,然后控制台cd到com目录,通过javah -jni 包名。包名。包名支出JNIInterface 的class,生成。h头文件,然后 src main 右键jni folder 起名jni,拷贝进去,在新建c文件,实现代码,如下:
// // Created by Administrator on 2016/5/3. // #include "com_example_mylibrary_JNIInterface.h" JNIEXPORT jstring JNICALL Java_com_example_mylibrary_JNIInterface_toTestJNI (JNIEnv *env, jobject j) { return (*env)->NewStringUTF(env,"This just a t io NDK JNI developer!"); } /* * Class: com_example_mylibrary_JNIInterface * Method: toTestJNI2 * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_example_mylibrary_JNIInterface_toTestJNI2 (JNIEnv *env, jobject j) { return (*env)->NewStringUTF(env,"This just a t io NDK JNI developer!"); }
然后至此,我们可以得到classes.jar和libmylibrary.so,可以搜索找到,会有很多个,jar包无所谓,我这里so拷贝的是x86版本,因为电脑虚拟机操作系统是x86 cpu的。
二、新建Android界面项目测试
1.写一个textview测试下:
public class MainActivity extends AppCompatActivity { private JNIInterface interf = new JNIInterface(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView v = (TextView)findViewById(R.id.tet); String a =interf.toTestJNI(); v.setText(interf.toTestJNI()); } }2.配置gradle
sourceSets { main { //jniLibs.srcDirs = [ 'src/main/jniLibs/'] jniLibs.srcDirs = ['libs'] //jni.srcDirs = ['src/main/jni', 'src/main/jniLibs/'] } }加上这句话。
引用第三方so这个网上很多方法,基本都的类似。然后这里的lbs是路径,是可以改的。我这里一开始的时候,总是提示找不到so库,原因是网上说的方法在src main下建立jnilibs文件夹,拷贝进去so,这样和这个libs是不匹配的,会找不到,所以写jbs,就拷贝到libs下。如图:
然后拷贝jar包到libs路径,然后右键add library即可。
完结:
至此运行整个项目即可通过jar包调用so库的接口,完美的实现打包jni方法,实现ui代码和so库等的分离。
资源下载:
一个是打包的完整代码,一个是调用的代码。
http://download.csdn.net/detail/villean/9510511
http://download.csdn.net/detail/villean/9510507