.so的创建和调用有一个特点,我们要知道.so的调用并不一定必须在Activity中进行,那么制作时也并不一定要在Activity中,但是,一旦.so制作成功,那么再调用时,调用的java类就必须跟制作.so时的java类(包括路径和类名)必须一致!

举个例子:拿上篇文章来说,我在创建.so时是在MainActivity中调用的,路径名是com.byl.jnitest,那么最终生成的.so想要在其他项目中使用,调用其的类就必须是com.byl.jnitest.MainActivity,不能是其它任何类,否则报错。这样一来岂不是局限性非常大,而且特别不人性化?是的,但是我前面说过,.so的调用并不一定必须在Activity中进行,制作时也并不一定要在Activity中,所以我们可以另外创建一个util类来调用.so,并最终将该类封装为一个jar和.so配套使用,由此我们也可以窥探出其他第三方sdk总是x个jar和x个so配对使用的原因!

好了,接下来我们重新建立一个AS项目jnitest2,随后创建一个专门调用so的java类JniUtil:

JniUtil.java:

package com.byl.jnitest2;

/**
 * Created by baiyuliang on 2016-4-5.
 */
public class JniUtil {

    public static native String getSec();//.so中的方法名

    static{
        System.loadLibrary("jnitest2");//加载.so
    }

}

MainActivity.java:

public class MainActivity extends AppCompatActivity {

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

        Log.e("jj", JniUtil.getSec());
    }
}

jni文件夹下的.h和.c文件:

注意.h的命名要和调用so的类名一致!

com_byl_jnitest2_JniUtil.h:(注意路径名)

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_byl_jnitest2_JniUtil */

#ifndef _Included_com_byl_jnitest2_JniUtil
#define _Included_com_byl_jnitest2_JniUtil
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_byl_jnitest2_JniUtil
 * Method:    getSec
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_byl_jnitest2_JniUtil_getSec
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

jnitest.c:

#include  <string.h>
#include  <jni.h>

jstring
Java_com_byl_jnitest2_JniUtil_getSec
   (JNIEnv* env,jobject thiz){
	return (*env)->NewStringUTF(env,"调用jni成功");
}

其它步骤不在书写,按照上篇文章的步骤,最终生成我们所要的so文件libjnitest2.so:

运行结果:

成功,好了,接下来我们看如何将这个so应用到其它项目中

首先我们要将JniUtil这个类打包成一个jar>>jniutil.jar:

接着我们再次创建一个新的AS项目jnitest3来测试生成的so和封装的jar,并将so和jar依次添加进项目中:

在MainActivity中调用so方法:

运行结果:

这样封装过后,对于so的调用就变得异常简单,那么对于一些项目中使用的密文则可以直接使用这种方法处理了!

经过这几篇文章,你是否对jni、so的生成过程以及使用有了一个初步的认识呢?

.so的封装调用的更多相关文章

  1. python(面向对象-类封装调用)

    一.面对对象思想 (1)大家肯定听过 Python 中”一切皆对象“的说法,但可能并不了解它的具体含义,只是在学习的时候听说 Python 是面向对象的编程语言,本节将向大家详细介绍 Python 面 ...

  2. HeadFirst设计模式笔记:(六)命令模式 —— 封装调用

    1.概念 将来自客户端的请求传入一个对象,从而使你可用不同的请求对客户进行参数化.用于“行为请求者”与“行为实现者”解耦,可实现二者之间的松耦合,以便适应变化.分离变化与不变的因素. 在面向对象的程序 ...

  3. iOS支付宝,微信,银联支付集成封装调用(下)

    一.越来越多的app增加第三方的功能,可能app有不同的页面但调用相同的支付方式,例如界面如下: 这两个页面都会使用第三方支付支付:(微信,支付宝,银联)如果在每一个页面都直接调用第三方支付的接口全部 ...

  4. Android对方向感应器的封装调用

    Android自动的SensorManager使用起来已经很方便,但由于一些情况我们希望对其中的功能进行封装: 只使用个别的sensor,功能相对单一 要对sensor返回的raw data进行算法处 ...

  5. python(类的封装调用/继承/多态)

    一.类的定义 类:用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例   对象:类实例化出来的叫做对象   对象和类的关系:类和对象的关系就像模具和铸 ...

  6. JavaScript函数封装调用

    举个列子:我们在写前端页面,经常会使用到Jquery文本框内容,来判断一下输入值是否符合,常见的写法: <script> function test(){ $("#ID" ...

  7. .netcore 3.1高性能微服务架构:封装调用外部服务的接口方法--HttpClient客户端思路分析

    众所周知,微服务架构是由一众微服务组成,项目中调用其他微服务接口更是常见的操作.为了便于调用外部接口,我们的常用思路一般都是封装一个外部接口的客户端,使用时候直接调用相应的方法.webservice或 ...

  8. 利用C++11可变模板,封装调用dll导出函数

    起因 开发中经常需要动态调用一些导出函数,试着利用C++11特性封装一下 尝试 常规使用 typedef int WINAPI (*TMessageBoxA)(HWND hWnd,LPCSTR lpT ...

  9. 可方便扩展的JIRA Rest Web API的封装调用

    JIRA是一个缺陷跟踪管理系统,被广泛应用于缺陷跟踪.客户服务.需求收集.流程审批.任务跟踪.项目跟踪和敏捷管理等工作领域,当我们需要把第三方业务系统集成进来时,可以调用他的API. JIRA本身的A ...

随机推荐

  1. hdu 5534(dp)

    Input The first line contains an integer T indicating the total number of test cases. Each test case ...

  2. java版的类似飞秋的局域网在线聊天项目

    原文链接:http://www.cnblogs.com/wangleiblog/articles/5323305.html 转载请注明 最近在弄一个java版的局域网在线聊天项目,功能跟飞秋差不多.p ...

  3. Linux 基本bash命令

    1.查看文件大小.内存大小.cpu信息.硬盘空间 显示当前目录所有文件大小的命令:ls -lht 内存空间.CPU信息.硬盘空间:htop.top(htop详解参考:http://blog.csdn. ...

  4. 如何避免 async/await 地狱

    简评:async/await 写着很爽,不过要注意这些问题. async/await 让我们摆脱了回调地狱,但是这又引入了 async/await 地狱的问题. 什么是 async/await 地狱 ...

  5. 如何为分布式系统优雅的更换RPC

    为啥需要更换RPC? 很多小伙伴都遇到过需要为分布式系统调用更换RPC的问题,为什么会遇到这种事呢?其实,在系统搭建初期,需求简单,架构简单,最重要的是请求量也少,所以很多系统都采用快速原型开发模式, ...

  6. jdk1.7和jdk1.8区别

    转自:http://www.2cto.com/kf/201307/225968.html 本文是我学习了解了jdk7和jdk8的一些新特性的一些资料,有兴趣的大家可以浏览下下面的内容. 官方文档:ht ...

  7. spark学习笔记01

    spark学习笔记01 1.课程目标 1.熟悉spark相关概念 2.搭建一个spark集群 3.编写简单spark应用程序 2.spark概述 spark是什么 是基于内存的分布式计算引擎,计算速度 ...

  8. AJAX 向后台发送带 List 集合的对象

    现有基类: public class School { int name; int address; List<Student> students = new ArrayList<S ...

  9. Python中enumerate用法详解

    enumerate()是python的内置函数.适用于python2.x和python3.xenumerate在字典上是枚举.列举的意思enumerate参数为可遍历/可迭代的对象(如列表.字符串)e ...

  10. 05_CRUD操作

      1.Params拦截器: 作用:Parameters拦截器将把表单字段映射到ValueStack栈的栈顶对象的各个属性中, 注意:如果某个字段在栈顶对象中没有对应的属性,则Params拦截器将尝试 ...