首先我先给大家推荐一个很好的博客哦,这个是我无意间看到的~~ 我首先给大家带来的是一个Helloworld的程序。
步骤会一步步贴图给出哦,至于现在的我会相信大家可以搞定的。
1 确保你已经安装了NKD(我目前用的是NDK r4) 还有就是希望大家要记得在自己的Eclipse上安装CDT插件哦,另外在编译的过程中我们还要安装Cygwin的,还得在Cygwin中配置ndk4(下面用的$NDK4就是我们自己配置的)
2 那就开始程序的开发了:
2.1 新建程序
新建一个Android程序叫HelloWorld。
package com.example.helloworld;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
public static native String getString();
static {
System.loadLibrary("HelloWorld");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
相信大家都只都这是干嘛的。
2.2 开始编译生成头文件。
看了很多帖子感觉有些帖子是转载的没有实际的自己的操作,我现在给大家一个很好用的方法:
先打开自己的命令行吧,我的已经安装了Cygwin了有点linux的意思,呵呵,不过没关系。
然后呢就可以看到在src下看到一个头文件了:
好了,这就搞定了第一步了
2.3 开始编译so库了,所谓的so库就是动态的链接库,window下用的是dll,我们现在用的是android系统(其内核还是Linux的)。
我们先得自己将我们刚才生成的.h头文件考到一个新建的jni的文件夹下,还得实现刚才的.h中的方法。
#include "com_example_helloworld_MainActivity.h"
JNIEXPORT jstring JNICALL Java_com_example_helloworld_MainActivity_getString
(JNIEnv *env, jobject obj)
{
char *str="Hello World";
return (*env)->NewStringUTF(env,str);
}
另外我们还得自己写一个Android.mk文件就相当于Linux的makeFile:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := HelloWorld
LOCAL_SRC_FILES := com_example_helloworld_MainActivity.c
include $(BUILD_SHARED_LIBRARY)
这个.mk我解释一下
**************************************************************
local_path就是本地文件,地位到当前的文件夹
$(CLEAR_VARS) 先clear下系统的变量
本地的模块(LOCAL_MODULE) HelloWorld就是我们要生成的so库的名字
包含的头文件(LOCAL_SRC_FILES) 就是我们自己写的源文件
*************************************************************
在Cygwin下编译生成so库:
好吧在bin文件夹下看一下吧:
有了so包了。 我们还需要让这个字符显示出来哦,来一起改下activity的代码:
package com.example.helloworld;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
public static native String getString();
private TextView helloText;
//加载的HelloWolrd.so
static {
System.loadLibrary("HelloWorld");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findView();
}
//找到在layout下的xml布局中的textview
private void findView() {
helloText = (TextView)findViewById(R.id.hello);
helloText.setText("JNIString "+getString());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
OK全部完成了。
附上代码吧
这是一个很小的demo,我们要实现的也很简单就是让JAVA层的能直接调用c层的实现,因为在很多的情况下我们需要通过c来直接调用系统的硬件的接口,其实我们对jni 的了解还是很少,我们就从android开始吧!
hello-jni在Java环境中的类MainActivity中声明的函数名为getString,前面要用到修饰符native,类HelloJni所在的包名为com.example.helloworld,需要用函数System.loadLibrary加载lib库HelloWorld.so,采用static修饰符确保只加载一次。然后按正常函数使用就行了。而在NDK这边,即C语言这层,函数命名要遵循Java_包_类_函数的命名方式,中间用下划线_进行连接,如上面所示,在包com.example.hellojni中的类HelloJni声明为stringFromJNI,则在C/C++文件中定义的函数名为JNIEXPORT jstring JNICALL Java_com_example_helloworld_MainActivity_getString,注意区分大小写。函数可以传参数,本例子中没有传入参数,只是有返回参数,返回参数的数据类型为jstring,即Java中的String类型。对于C/C++中与上面的Java环境打交道的数据类型可以参照JNI,具体可访问官方网站http:// java.sun.com/docs/books/jni/。对于函数JNIEXPORT jstring JNICALL Java_com_example_helloworld_MainActivity_getString中的两个参数env和thiz是系统必须的,如果需要输入参数,必须再增加参数。
精品贴:
讲到了c/c++的不同实现:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=180287