本文简单介绍利用jni传一个字符串到android界面。
1、 建立一个android的应用程序
2、 修改java文件
MainActivity.java文件
package com.scy.jnitest;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity
{
static
{
System.loadLibrary("MainActivity");
}
private static native Stringprint();
private TextView textView;
@Override
protected void onCreate(BundlesavedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView =(TextView)findViewById(R.id.text);
textView.setText(print());
}
}
3、 编译生成头文件
这一步需要注意的是文件夹的定位,必须要定位到src文件夹下,在执行javah com.scy.jnitest.MainActivity才能生效,如果直接定位到类文件或者java文件的话,就会出现错误。
头文件内容:
/* DONOT EDIT THIS FILE - it is machine generated */
#include<jni.h>
/*Header for class com_scy_jnitest_MainActivity */
#ifndef _Included_com_scy_jnitest_MainActivity
#define _Included_com_scy_jnitest_MainActivity
#ifdef __cplusplus
extern"C" {
#endif
/*
* Class: com_scy_jnitest_MainActivity
* Method: print
* Signature: ()Ljava/lang/String;
*/
JNIEXPORTjstring JNICALL Java_com_scy_jnitest_MainActivity_print
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
4、 根据头文件编写.cpp文件
新建一个jni文件夹,在该文件夹下新建一个MainActivity.cpp文件,根据头文件中的相关代码编写(可以直接拷贝,但是注意后面的“;”,我上次就是多出来一个分号,找了半天的错误,崩溃)。这里如果用到java和c的数据的传输,建议大家看下面链接的文章,这里就不多说了。http://www.blogjava.net/china-qd/archive/2006/04/29/44002.html
http://android.tgbus.com/Android/androidnews/201206/438987.shtml
也可以自己去百度orGoogle搜。
5、 生成动态链接库,如下图所示
生成完成之后,jni文件夹下多出来这四个文件,。
6、 编写Android.mk 和Application.mk这两个文件,关于这两个文件的重要性和语法规则,大家可以网上搜。http://www.cnblogs.com/likwo/archive/2012/08/08/2629075.html
上面的链接上的内容主要讲解了Android.mk的语法规范。
Android.mk文件的内容:
LOCAL_PATH := $(callmy-dir)
include$(CLEAR_VARS)
LOCAL_MODULE:= MainActivity
LOCAL_SRC_FILES := MainActivity.cpp
include$(BUILD_SHARED_LIBRARY)
好,我们来解释一下这几行代码:
LOCAL_PATH := $(call my-dir)
一个Android.mk file首先必须定义好LOCAL_PATH变量。它用于在开发树中查找源文件。在这个例子中,宏函数’my-dir’, 由编译系统提供,用于返回当前路径(即包含Android.mkfile文件的目录)。
include $( CLEAR_VARS)
CLEAR_VARS由编译系统提供,指定让GNU MAKEFILE为你清除许多LOCAL_XXX变量(例如LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, 等等...),
除LOCAL_PATH 。这是必要的,因为所有的编译控制文件都在同一个GNUMAKE执行环境中,所有的变量都是全局的。
LOCAL_MODULE := MainActivity
LOCAL_MODULE变量必须定义,以标识你在Android.mk文件中描述的每个模块。名称必须是唯一的,而且不包含任何空格。注意编译系统会自动产生合适的前缀和后缀,换句话说,一个被命名为'foo'的共享库模块,将会生成'libfoo.so'文件。
重要注意事项
如果你把库命名为‘libMainActivity’,编译系统将不会添加任何的lib前缀,也会生成libMainActivity.so,这是为了支持来源于Android平台的源代码的Android.mk文件,如果你确实需要这么做的话。
LOCAL_SRC_FILES := MainActivity.cpp
LOCAL_SRC_FILES变量必须包含将要编译打包进模块中的C或C++源代码文件。注意,你不用在这里列出头文件和包含文件,因为编译系统将会自动为你找出依赖型的文件;仅仅列出直接传递给编译器的源代码文件就好。【注意,默认的C++源码文件的扩展名是’.cpp’. 指定一个不同的扩展名也是可能的,只要定义LOCAL_DEFAULT_CPP_EXTENSION变量,不要忘记开始的小圆点(也就是定义为‘.cxx’,而不是‘cxx’)(当然这一步我们一般不会去改它)】
include $(BUILD_SHARED_LIBRARY)
BUILD_SHARED_LIBRARY是编译系统提供的变量,指向一个GNU Makefile脚本(应该就是在build/core目录下的shared_library.mk),负责收集自从上次调用'include $(CLEAR_VARS)'以来,定义在LOCAL_XXX变量中的所有信息,并且决定编译什么,如何正确地去做。并根据其规则生成静态库。同理对于静态库。
Application.mk的内容
APP_ABI:= armeabi armeabi-v7a
正是因为这句话,就会在这两个文件夹下生成的libMainActivity.so。
armeabi和armeabi-v7a是表示cpu的类型,我们知道一般的手机或平板都是用arm的cpu(mips的就悲催的被忽视了),不同的cpu的特性不一样,armeabi就是针对普通的或旧的arm cpu,armeabi-v7a是针对有浮点运算或高级扩展功能的arm cpu。因此armeabi通用性强,但速度慢,而v7a能充分发挥v7a CPU的能力。更多信息,大家可以谷歌。
7、 最后,利用NDK-build编译,生成libMainActivity.so.
这样点击右键运行就OK了!
最后的效果图是: