zoukankan      html  css  js  c++  java
  • Android jni编辑.so库

    引自:http://www.cnblogs.com/sevenyuan/p/4202759.html

    1. 在Eclipse中创建项目:TestJNI

    2. 新创建一个class:TestJNI.java

    复制代码
    package com.wwj.jni;
    
    public class TestJNI {
        public native boolean Init();
        public native int Add(int x, int y);
        public native void Destory();
    }
    复制代码
    以上代码声明三个本地方法。
     
    3. 编译JNI
    找到Android项目中bin目录下,会有classes文件夹,Eclipse自动为我们生成的字节码文件就在这个目录下。
    我们在该路径下,使用javah命令,生成我们想要得到的.h头文件,如下图所示:
    javah -jni 包名
     
    执行javah -jni com.wwj.jni.TestJNI命令之后,会在classes目录下生成头文件:com_wwj_jni_TestJNI.h
    将它复制到jni文件夹下,打开如下:
    复制代码
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_wwj_jni_TestJNI */
    
    #ifndef _Included_com_wwj_jni_TestJNI
    #define _Included_com_wwj_jni_TestJNI
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_wwj_jni_TestJNI
     * Method:    Init
     * Signature: ()Z
     */
    JNIEXPORT jboolean JNICALL Java_com_wwj_jni_TestJNI_Init
      (JNIEnv *, jobject);
    
    /*
     * Class:     com_wwj_jni_TestJNI
     * Method:    Add
     * Signature: (II)I
     */
    JNIEXPORT jint JNICALL Java_com_wwj_jni_TestJNI_Add
      (JNIEnv *, jobject, jint, jint);
    
    /*
     * Class:     com_wwj_jni_TestJNI
     * Method:    Destory
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_com_wwj_jni_TestJNI_Destory
      (JNIEnv *, jobject);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    复制代码
    以上代码就是通过javah命令生成jni层代码。
    出现的问题:

    当在Android项目路径下,使用javah指令生成.h文件时,javah -classpath bin/classes -d jni com.example.myhellojni.MainActivity 

    出现--->错误:无法访问android.app.Activity 找不到android.app.Activity的类文件。

    其中 -classpath bin:表示类的路劲

    其中 -d jni: 表示生成的头文件存放的目录

    其中 com.example.hellojni.HelloJni 则是完整类名


    【解决办法】

    进入src目录,使用javah -d ../jni com.example.myhellojni.MainActivity 指令代替。

    其中 -d:建立一个目录。

    其中../jni :在上级目录的jni文件下生成头文件。

    原理:.java文件也不用编译可以直接生成.h文件。 

    直接在jni文件夹中生成.h文件

     
    4. 使用C/C++实现JNI
    在jni文件夹下,创建com_wwj_jni_TestJNI.h对应的cpp文件:com_wwj_jni_TestJNI.cpp
     
    我们再添加两个文件Add.h,Add.cpp,具体实现放在这两个文件中来完成。
    Add.h
    复制代码
    #ifndef _TEST_JNI_ADD_H_
    #define _TEST_JNI_ADD_H_
    
    class CAdd {
    public:
        CAdd();
        ~CAdd();
    
        int Add(int x, int y);
    };
    
    #endif
    复制代码

    Add.cpp

    复制代码
    #include "Add.h"
    
    CAdd::CAdd() {
    
    }
    
    CAdd::~CAdd() {
    
    }
    
    int CAdd::Add(int x, int y) {
        return x + y;
    }
    复制代码

    com_wwj_jni_TestJNI.cpp的实现:

    复制代码
    #include <stdio.h>
    #include <stdlib.h>
    #include "com_wwj_jni_TestJNI.h"
    #include "Add.h"
    
    CAdd *pCAdd = NULL;
    
    JNIEXPORT jboolean JNICALL Java_com_wwj_jni_TestJNI_Init(JNIEnv *env,
            jobject obj) {
        if (pCAdd == NULL) {
            pCAdd = new CAdd;
        }
        return pCAdd != NULL;
    }
    
    JNIEXPORT jint JNICALL Java_com_wwj_jni_TestJNI_Add(JNIEnv *env, jobject obj,
            jint x, jint y) {
        int res = -1;
        if (pCAdd != NULL) {
            res = pCAdd->Add(x, y);
        }
        return res;
    }
    
    JNIEXPORT void JNICALL Java_com_wwj_jni_TestJNI_Destory(JNIEnv *env, jobject obj)
    {
        if (pCAdd != NULL)
        {
            pCAdd = NULL;
        }
    }
    复制代码
    5. 创建mk文件,并使用ndk-build命令生成.so动态链接库文件
    在jni目录下创建Android.mk文件如下:
    复制代码
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := TestJNI
    
    LOCAL_SRC_FILES := com_wwj_jni_TestJNI.cpp
    LOCAL_SRC_FILES += Add.cpp
    
    include $(BUILD_SHARED_LIBRARY)
    复制代码
    其中
    LOCAL_PATH是C/C++代码所在目录,也就是我们的jni目录。
    LOCAL_MODULE是要编译的库的名称。编译器会自动在前面加上lib,在后面加上.so。
    LOCAL_SRC_FILES是要编译的C/C++文件。
     
    然后我还需要在Android项目根目录下创建Application.mk文件:
    APP_PROJECT_PATH := $(call my-dir)
    APP_MODULES := TestJNI
    写完了这两个mk文件,我们就可以用ndk来为我们生成相应的动态链接库了。前提你需要下载NDK,并把NDK路径配置到path环境变量中去,笔者配置的路径是:D:Cocos2dxandroid-ndk-r9d,具体视个人情况而定。
    进入Application.mk文件所在目录,在命令行中使用ndk-build生成.so文件
    编译成功后会在工程目录的libs/armeabi目录下生成一个libTestJNI.so文件。
     
    项目结构会变成如下:
    6. 在Java中调用JNI
    复制代码
    package com.wwj.jni;
    
    import android.os.Bundle;
    import android.widget.TextView;
    import android.app.Activity;
    
    public class TestJNIActivity extends Activity {
    
        private TextView textView;
        static {
            // 加载动态库
            System.loadLibrary("TestJNI");
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            textView = (TextView) findViewById(R.id.textview);
    
            TestJNI testJNI = new TestJNI();
            // 调用native方法
            boolean init = testJNI.Init();
            if (init == true) {
                // 调用Add函数
                int sum = testJNI.Add(100, 150);
                textView.setText("你真是个" + sum);
            } else {
                textView.setText("你比二百五还要二百五");
            }
            testJNI.Destory();
        }
    }
    复制代码

    运行项目,效果图如下:

  • 相关阅读:
    self 和 super 关键字
    NSString类
    函数和对象方法的区别
    求两个数是否互质及最大公约数
    TJU Problem 1644 Reverse Text
    TJU Problem 2520 Quicksum
    TJU Problem 2101 Bullseye
    TJU Problem 2548 Celebrity jeopardy
    poj 2586 Y2K Accounting Bug
    poj 2109 Power of Cryptography
  • 原文地址:https://www.cnblogs.com/Anita9002/p/5502040.html
Copyright © 2011-2022 走看看