首先通过NDK自带的例子来初步了解NDK的开发

1. Java类文件

/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.example.hellojni;

import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;


public class HelloJni extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        /* Create a TextView and set its content.
         * the text is retrieved by calling a native
         * function.
         */
        TextView  tv = new TextView(this);
        tv.setText( stringFromJNI() );
        setContentView(tv);
    }

    /*
     * 调用libhello-jni.so库中的stringFromJNI()方法
     * 注意声明的时候需要包含"native",表示是本地方法
     */
    public native String  stringFromJNI();

    /*
     * 加载libhello-jni.so库,省略了头lib和尾.so
     * static{}在程序加载的时候就调用
     */
    static {
        System.loadLibrary("hello-jni");
    }
}

2. 本地C代码部分

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

/*
	函数命名规则:
      Java开头,接着是包名的每一段,然后是类名,最后是Java中调用的方法名,中间都用下划线隔开。
      第一个参数JNIEnv* env和第二个参数jobject thiz都是必须的,后面的才是Java中传递进来的参数
 */
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
    return (*env)->NewStringUTF(env, "Hello from JNI !");//字符串的操作见NDK概述
}

 

 

 

 

 

 

 

          

3. 在工程目录编译jni文件夹生成so文件,则可以通过Eclipse加载工程调试了。

 

第二部分:进阶

     通过上面的例子分析,我们知道了怎么调用动态库,怎么引用动态库中的方法,以及动态库中方法的命名。下面我们了解怎么在本地C代码中添加一个方法,给java调用。

我们以添加一个add方法为例,方法原型为:int addFromJNI(int a,int b)

A. 在本地C代码中添加add方法,并实现。


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

/*
	函数的命名规则:
	Java开头,接着是包名的每一段,然后是类名,最后是Java中调用的方法名,中间都用下划线隔开。
	第一个参数JNIEnv* env和第二个参数jobject thiz都是必须的,后面的才是Java中传递进来的参数。
 */
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
    return (*env)->NewStringUTF(env, "Hello from JNI !");
}

jint Java_com_example_hellojni_HelloJni_addFromJNI(
			JNIEnv* env,jobject thiz,jint a,jint b)
{
	return a + b;	
}

B. 编译mk文件,生成so文件

    $NDK/ndk-build       //$NDK环境变量设置的NDK目录 
C. java 源代码

package com.example.hellojni;
import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;


public class HelloJni extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        /* Create a TextView and set its content.
         * the text is retrieved by calling a native
         * function.
         */
        TextView  tv = new TextView(this);
        tv.setText( stringFromJNI() +"****" + addFromJNI(3, 4));
        setContentView(tv);
    }

    /*
     * 调用libhello-jni.so库中的stringFromJNI()方法
     * 注意声明的时候需要包含"native",表示是本地
     */
    public native String  stringFromJNI();

    /*
     * 调用新增加的addFromJNI方法
     */
    public native int addFromJNI(int a,int b);
    /*
     * 加载libhello-jni.so库,省略了头lib和尾.so
     * static{}在程序加载的时候就调用
     */
    static {
        System.loadLibrary("hello-jni");
    }
}

D. 加载运行,则看到刚添加的函数生效了

    

相关文章:

  • 2021-07-19
  • 2021-05-25
  • 2021-10-21
  • 2022-12-23
猜你喜欢
  • 2021-04-25
  • 2021-09-07
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-07-19
相关资源
相似解决方案