Quantcast
Channel: CSDN博客推荐文章
Viewing all articles
Browse latest Browse all 35570

Android游戏开发----JNI小结

$
0
0

Android游戏开发必不可少是要接触JNI的,除非你什么只是写一些普通的小游戏。特别是用3D、OpenGL等时,JNI是基础。


一、关于NDK

NDK全称是(Native Development Kit),作用就是方便在Android中调用C、C++写的东西,因为C的效率高,底层的东西大都是用C写的。

1、NDK是一系列工具的集合。
* NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。这些工具对开发者的帮助是巨大的。
* NDK集成了交叉编译器,并提供了相应的mk文件隔离平台、CPU、API等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。
* NDK可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作。
2、NDK提供了一份稳定、功能有限的API头文件声明。
Google明确声明该API是稳定的,在后续所有版本中都稳定支持当前发布的API。从该版本的NDK中看出,这些API支持的功能非常有限,包含有:C标准库(libc)、标准数学库(libm)、压缩库(libz)、Log库(liblog)。

二、用NDK写Hello World

NDK的安装部署等这里就不说了。

NDK写Hello World一般步骤


按照步骤一步步来,即可实现在Android程序中调用C函数。

程序功能:有两个按钮,分别对应调用两个C函数。

Activity代码部分

public class MainActivity extends Activity
{
	//静态代码块在类第一次被加载的时候调用
	static
	{
		System.loadLibrary("hello");//名字还是叫hello
	}

	//定义一个本地方法, 在jni目录中的c代码来实现这个方法
	public native String helloFromC();
	
	//带下划线, 因为C方法中声明也是下划线. 有区别.
	public native String hello_c();

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

		//1. 不带下划线的本地函数
		Button button1 = (Button) findViewById(R.id.button1);

		button1.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				Toast.makeText(MainActivity.this, helloFromC(),
						Toast.LENGTH_SHORT).show();//Toast
			}
		});
		
		//带下划线的本地函数
		Button button2 = (Button) findViewById(R.id.button2);

		button2.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				Toast.makeText(MainActivity.this, hello_c(),
						Toast.LENGTH_SHORT).show();//Toast
			}
		});
	}

	@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;
	}

}

本地方法中带下划线时,C代码中的方法名也要进行相应的变化。



C代码部分

#include<stdio.h>
#include<jni.h>
#include "com_example_ndkhello_MainActivity.h"

#include <android/log.h>
#define LOG_TAG "System.out.c"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

/*直接写:类型必须对应, 方法名必须按规定, 参数固定*/
jstring Java_com_example_ndkhello_MainActivity_helloFromC(JNIEnv * env, jobject obj)
{
	LOGI("this is a logcat from c");//在logcat中显示
	//不能是中文.  (*(*env)).NewStringUTF 是一样的
	return (*env)->NewStringUTF(env,"hello , my NDK!");
}

/*用javah生成头文件, 然后写. 这个是一般的做法. 注意要引入头文件\写函数参数*/
JNIEXPORT jstring JNICALL Java_com_example_ndkhello_MainActivity_hello_1c
  (JNIEnv *env, jobject obj)
{
	return (*(*env)).NewStringUTF(env,"hello , my NDK_____!");
}

注意:方法名是固定的,C方法名为Java_包名(以下划线分开)_Activity_方法名 ,包名与方法名中最好不要包含下划线,一般用Javah工具来生成最好。

以上代码包含了在C代码中使用logcat来进行调试。


Android.mk部分

LOCAL_PATH := $(call my-dir)

   include $(CLEAR_VARS)

   LOCAL_MODULE    := hello
   LOCAL_SRC_FILES := hello.c

	LOCAL_LDLIBS += -llog #引入log库
   include $(BUILD_SHARED_LIBRARY)


有关makefile文件的写法,可以看看这里http://zensheno.blog.51cto.com/2712776/501371


源码下载http://download.csdn.net/detail/xn4545945/5511051


转载请注明出处:http://blog.csdn.net/xn4545945  



作者:xn4545945 发表于2013-6-3 21:13:06 原文链接
阅读:40 评论:0 查看评论

Viewing all articles
Browse latest Browse all 35570

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>