Android中调用jni的方法

  • JIN简介

  • JNI是Java Native Interface的缩写,中文为JAVA本地调用。从Java1.1开始,Java Native Interface(JNI)标准成为 java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。
  • 首先通过一个实例来随意感受下
  • 环境说明: windows7 X86 ,jdk1.8,VS2013
  • 程序清单:HelloWorld.java
    public class HelloWorld{
        static{
            System.loadLibrary("HelloWorld");
        }
    
        public native String SayHello();        //声明native方法
        public static void main(String[] args){
            HelloWorld hello = new HelloWorld();
            System.out.println(hello.SayHello());        //调用native方法
        }
    }
  • 命令:javac HelloWorld.java

  •           javah –jni HelloWorld

  • 我们会发现在工作目录除了常见的HelloWorld.class外,还生成了HelloWorld.c。这个头文件是由javah –jni HelloWorld这个命令生成的

  • javah –help

  • 用法:
      javah [options] <classes>
    其中, [options] 包括:
      -o <file>                输出文件 (只能使用 -d 或 -o 之一)
      -d <dir>                 输出目录
      -v  -verbose             启用详细输出
      -h  --help  -?           输出此消息
      -version                 输出版本信息
      -jni                     生成 JNI 样式的标头文件 (默认值)
      -force                   始终写入输出文件
      -classpath <path>        从中加载类的路径
      -cp <path>               从中加载类的路径
      -bootclasspath <path>    从中加载引导类的路径
    <classes> 是使用其全限定名称指定的
    (例如, java.lang.Object)。

    如果是引入包名的java文件,还有一些需要注意的地方,具体请参见:http://www.cnblogs.com/charley_yang/archive/2011/03/13/1983038.html

  • 这个头文件主要是为了让C++代码包含进去的,看看生成后的文件大概长啥样

  • 程序清单:HelloWorld.h

  • /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class HelloWorld */
    
    #ifndef _Included_HelloWorld
    #define _Included_HelloWorld        //防止重复引用
    #ifdef __cplusplus
    extern "C" {                //按照C语言方式编译和连接的外部变量
    #endif
    /*
     * Class:     HelloWorld
     * Method:    SayHello
     * Signature: ()Ljava/lang/String;        //返回值类型
     */
    JNIEXPORT jstring JNICALL Java_HelloWorld_SayHello
      (JNIEnv *, jobject);
    
    #ifdef __cplusplus
    }
    #endif
    #endif

    创建一个控制台工程,选择dll项目,把上述生成的HelloWorld.h拷贝到工程文件夹下并添加到项目中,添加包含目录\jdk1.8.0_25\include;\jdk1.8.0_25\include\win32

    程序清单:HelloWorld.cpp
    #include "HelloWorld.h"
    
    //****************************************************************
    //
    //功能:c++字符转换成jstring
    //
    //思路:
    //
    //参数:
    //
    //返回:TURE or FALSE
    //
    //作者:zhangzq
    //
    //日期:2014/11/06
    //
    //****************************************************************
    jstring stoJstring(JNIEnv* env, const char* pat)
    {
        jclass strClass = env->FindClass("Ljava/lang/String;");
        jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
        jbyteArray bytes = env->NewByteArray(strlen(pat));
        env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);
        jstring encoding = env->NewStringUTF("utf-8");
        return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
    }
    
    JNIEXPORT jstring JNICALL Java_HelloWorld_SayHello(JNIEnv * env, jobject)
    {
        jstring jstrRe = stoJstring(env, "Hello Java Native Interface");
        return jstrRe;
    }

    编译一下,OK,生成HelloWorld.dll。把该dll拷贝到java的工具目录中,我们来试试效果:

    QQ截图20141106145144

  •  

  • Android环境测试

    安装jdk(测试版本1.8)

    下载并解压带android sdk版本的Eclipse,下载地址:https://dl.google.com/android/adt/adt-bundle-windows-x86-20140702.zip

    下载并解压ndk,下载地址:

    http://dl.google.com/android/ndk/android-ndk32-r10-windows-x86.zip

    使用Eclipse创建Android工程

  • 右击工程文件夹,RunAs->Android Application,测试是否能正常使用编译Android程序

  • 右击工程文件夹,Android Toos->Add Native Support(如果无此菜单项,到Eclipse mark中下载Android Develop Toolkit插件),,然后输入要新建的so文件名

  • image

  • 创建完成后,文件目录大概是这个样子的

  • image

  • 修改MyJni文件中的内容

  • 程序清单:MyJni.cpp

    #include <jni.h>
    #include<string.h>
    extern "C"        //如果不加这个,会引起native method错误
    {
    jstring     //返回值是java类型的字符串
    //**********************************************************
    //函数名命名规则:
    //1. 在首部加上Java_,注意首字母大写
    //2.使用该函数的java源码所在的文件路径,目录之间用"_"分割
    //3.去掉文件的后缀名,加上被java中调用的函数名
    //
    //***********************************************************
    Java_com_sunjor_testjni_MainActivity_SayHello( JNIEnv* env,
                                                      jobject thiz )
        {
            //return (*env)->NewStringUTF(env, "Hello from JNI !");        //后缀名为.c时使用
            return env->NewStringUTF((char*) "Hello from JNI !");        //后缀名为.cpp时使用
        }
    
    }

 

修改自动生成的MainActivity.java中的代码

package com.sunjor.testjni;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;


public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        /* Create a TextView and set its content.
         * the text is retrieved by calling a native
         * function.
         */
        TextView  tv = new TextView(this);
        tv.setText( SayHello() );
        setContentView(tv);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    /* A native method that is implemented by the
     * 'MyJni' native library, which is packaged
     * with this application.
     */
    public native String  SayHello();
    /* this is used to load the 'MyJni' library on application
     * startup. The library has already been unpacked into
     * /data/data/com.sunjor.TestJni/lib/libMyJni.so at
     * installation time by the package manager.
     */
    static {
        System.loadLibrary("MyJni");
    }
}

重新再试一次,看下效果-.-

Screenshot_2014-11-11-14-54-40

转载于:https://www.cnblogs.com/sunjor/p/4078180.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值