android 中调用 so 动态链接库

之前已经说过如何在 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_MODULELOCAL_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

请输入图片描述

5、右键选择 JNIDemo 项目,选择 Properties 选中左侧 C/C++ Build 选项,然后在 Builder Setting 选项卡中将 Build command 的值更改为你的电脑上 NDK 的构建文件绝对路径 如:D:\android-ndk-r9\ndk-build.cmd 然后切换到 Behaviour 选项卡,将 BuildIncremental 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 动态链接库就完成啦~~

最后修改:2017/09/07 11:22
如果觉得我的文章对你有用,请随意赞赏

发表评论

颜文字