android 中调用 so 动态链接库

时间:2022-01-26 15:53:11

之前已经说过如何在 linux 中使用 java 调用 so 动态链接库

这里来说一下在 android 中调用 so 动态链接库

作者之前也认为能够使用 java 调用 so 动态链接库之后便可以在 android 同样实现,但是发现将 so 文件导入 android 项目后,启动时导入动态链接库总是报错

错误为:Cannot load libraray 、not a avlid ELF 。。。 具体错误描述记不太清楚了,如果有大神知道具体原因麻烦留言告知下小弟

废话不说了,开始吧


在 android 中使用 so 动态链接库需要使用到 NDK

目前最新版为 android-ndk-r9

首页地址:http://developer.android.com/tools/sdk/ndk/index.html

下载地址:https://dl.google.com/android/ndk/android-ndk-r9-windows-x86.zip

下载完成后解压到电脑中,路径中不可出现中文名称


1、新建 Android Application Peoject,项目名称为 JNIDemo

2、在项目根目录下建立 jni 目录,将需要编译的 .c 文件拷贝到 jni 目录下

3、在 jni 目录下建立 Android.mk 文件并编辑

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := main
LOCAL_SRC_FILES := source.c

include $(BUILD_SHARED_LIBRARY)

我们需要修改的只有 LOCAL_MODULE 和 LOCAL_SRC_FILES 的值

LOCAL_MODULE 指定生成的 so 文件的名称,生成成功后会自动为该文件添加 lib 前缀和 .so 后缀,即生成成功的完整文件名为 libmain.so

LOCAL_SRC_FILES 指定的是需要编译的 c 文件

4、将 JNIDemo 转换为 C/C++ 项目

在 JNIDemo 项目上右键 New >> Other >> C/C++ >> Convert to a C/C++ Project

进入如下界面后选项如下图,配置完成后 Finish

android 中调用 so 动态链接库


5、右键选择 JNIDemo 项目,选择 Properties

选中左侧 C/C++ Build 选项,然后在 Builder Setting 选项卡中将 Build command 的值更改为你的电脑上 NDK 的构建文件绝对路径

如:D:\android-ndk-r9\ndk-build.cmd

然后切换到 Behaviour 选项卡,将 Build(Incremental build)的值删掉

最后在左侧的列表中展开 C/C++ General ,选中 Paths and Symbols,在右侧 Languages 中选中 GUN C,然后点击 Add,选择 File System

指定到如下路径下:D:\android-ndk-r9\platforms\android-8\arch-arm\usr\include

其中 android-8 为你的项目中使用的 sdk 版本,需要对应上,然后点击 OK,接着在项目上点击右键,选择 Build Project

构建完项目之后会发现项目中的 libs/armeabi 目录下已经添加好了我们指定的 libmain.so 文件,那我们现在就可以开始准备测试了~~

注:本库中使用的接口文件代码 source.c

#include "stdio.h"
#include "jni.h"

JNIEXPORT jstring JNICALL Java_com_hongquan_JNIInterfaces_sayHi(JNIEnv *env, jobject jo, jstring name)
{
return name;
}

6、在 JNIDemo 中新建类 JNIInterface,包名为 com.hongquan,代码如下

package com.hongquan;

public class JNIInterfaces {

// 载入动态链接库
static {
System.loadLibrary("main");
}

// 声明动态库接口
public native String sayHi(String str);

}

7、在 JNIDemo 项目的启动类中调用接口函数进行测试

package com.hongquan;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

JNIInterfaces lib = null;

TextView tvInfo;
EditText etInfo;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

lib = new JNIInterfaces();

tvInfo = (TextView) findViewById(R.id.txtInfo);
etInfo = (EditText) findViewById(R.id.etInfo);
findViewById(R.id.myBtn).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (etInfo.getText().toString().trim().length() <= 0) {
Toast.makeText(getApplicationContext(), "请输入文本内容", 1).show();
return;
}
tvInfo.setText("so return: " + etInfo.getText());
}
});

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return false;
}

}


android 中调用 so 动态链接库就完成啦~~

so 动态链接库下载地址:http://pan.baidu.com/s/1Bqsop

JNIDemo 项目下载地址:http://pan.baidu.com/s/1668Z8