现在的位置: 首页 > 综合 > 正文

第一个NDK程序

2013年08月16日 ⁄ 综合 ⁄ 共 3802字 ⁄ 字号 评论关闭

之前写了第一个JNI程序,有翻译了一篇NDK的入门教程,今天从头到尾自己写了一个。

环境:linux+ndk r6

开始之前:java和ndk的环境变量已经设置好

目标:一个简单的例子,从c中传给java int数组和字符串数组

开始:

新建一个项目,名称为FirstNDK

一个包是package com.linc.FirstNDK;放activity

另一个是package com.linc.lib;放lib文件,主要处理jni

布局:两个按钮+一个textview

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<Button
	android:id="@+id/btnOne"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="int Array!"
/>
<TextView  
	android:id="@+id/Result"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Result:"
    />
<Button
	android:id="@+id/btnTwo"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="string Array!"
/>    
</LinearLayout>

package com.linc.lib包下新建一个类FirstLib

package com.linc.lib;


public class FirstLib {
	// Native implementation  
	static {  
	System.loadLibrary("FirstLib"); 
	}  
	
	//传递数组
	public static native int[] intMethod();
	//传递字符串数组
	public static native String[] stringMethod();
}

这里主要有两个本地方法,

下面用它生成jni的头文件:用终端来到项目bin目录,

[linc@localhost bin]$ java -jni com.linc.lib.FirstLib

项目中新建一个jni目录,用来存放jni相关文件,并把刚刚生成的头文件放进去

[linc@localhost bin]$ mv com_linc_lib_FirstLib.h ../jni

在jni中新建一个c文件与上面的对应叫FirstLib.c,

#include "com_linc_lib_FirstLib.h"
const static int length=10;

//传递整型数组
JNIEXPORT jintArray JNICALL Java_com_linc_lib_FirstLib_intMethod
  (JNIEnv *env, jclass obj)
{
	jintArray array;//数组
	array=(*env)->NewIntArray(env,10);
	int i=1;
	for(;i<=10;++i)
	{
		(*env)->SetIntArrayRegion(env,array,i-1,1,&i);
	}

	//获取数组长度
	int len=(*env)->GetArrayLength(env,array);

	//获得数组中的所有元素
	jint* elems=(*env)->GetIntArrayElements(env,array,0);

	return array;
}

//字符串数组
JNIEXPORT jobjectArray JNICALL Java_com_linc_lib_FirstLib_stringMethod
  (JNIEnv *env, jclass obj)
{
	jclass class=(*env)->FindClass(env,"java/lang/String");
	jobjectArray string=(*env)->NewObjectArray(env,(jsize)length,
			class,0);
	jstring jstr;
	char* _char[]={"my ","name ","is ",
					"linc!!","正在","学习",
					"JNI","和","NDK","技术!"
					};
	int i=0;
	for(;i<length;++i)
	{
		jstr=(*env)->NewStringUTF(env,_char[i]);
		(*env)->SetObjectArrayElement(env,string,i,jstr);
	}

	return string;
}

在jni目录下新建一个mk文件,Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := FirstLib
LOCAL_SRC_FILES := FirstLib.c
include $(BUILD_SHARED_LIBRARY)

好,下面将其编译成共享库:回到项目目录

[linc@localhost FirstNDK]$ cd ..
[linc@localhost FirstNDK]$ ndk-build
Compile thumb  : FirstLib <= FirstLib.c
SharedLibrary  : libFirstLib.so
Install        : libFirstLib.so => libs/armeabi/libFirstLib.so

下面在activity中调用之:

package com.linc.FirstNDK;


import java.io.UnsupportedEncodingException;

import com.linc.lib.FirstLib;
import com.linc.lib.PersonalInfo;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class FirstNDK extends Activity {
	TextView textResult;  
	Button buttonOne;  
	Button buttonTwo;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        textResult = (TextView) findViewById(R.id.Result);  
        buttonOne = (Button) findViewById(R.id.btnOne);  
        buttonOne.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				int[] nums=FirstLib.intMethod();
				for(int i=0;i<nums.length;++i)
				{
					textResult.append("  "+nums[i]);
				}
			}
		}); 
        
        buttonTwo = (Button) findViewById(R.id.btnTwo);  
        buttonTwo.setOnClickListener(btnTwo_Click);
    }
    
    private OnClickListener btnTwo_Click = new OnClickListener()
    {
    	public void onClick(View v)
    	{    		
    		String[] string=FirstLib.stringMethod();
    		for(int i=0;i<string.length;++i)
    		{
    			try {
    				string[i]=new String(string[i].getBytes("gb2312"),"GBK");
    			} catch (UnsupportedEncodingException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			textResult.append("  "+string[i]);
    		}
    	}
    };
	
}

最后就可以运行看效果了!
ndk的使用,首先要具备jni的相关知识,在本blog中有相关记载。

希望大家用ndk来开发游戏时,玩的开心!

抱歉!评论已关闭.