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

来源:互联网 发布:二合一沐浴露 知乎 编辑:程序博客网 时间:2024/05/16 14:02

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();@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//1. 不带下划线的本地函数Button button1 = (Button) findViewById(R.id.button1);button1.setOnClickListener(new OnClickListener(){@Overridepublic 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(){@Overridepublic void onClick(View v){Toast.makeText(MainActivity.this, hello_c(),Toast.LENGTH_SHORT).show();//Toast}});}@Overridepublic 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.cLOCAL_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  


0 0
原创粉丝点击