/*http://my.oschina.net/lifj/blog/177087*/


上一篇讲了怎么配置NDK的开发环境。这次记录一下写一个Hello Jni的最简单的Android程序。

一。新建Android程序工程。

这里,我们需要做一下几步:
1.Layout中添加TextView的id。
2.MainActivity中声明native方法。
3.MainActivity中调用native方法。

我们这里先不loadLibrary。先load总感觉我的库还没有呢,先load做什么?有点莫名其妙。当然,你也可以先loadLibrary。看个人习惯了。

下面详细说明:
1.新建Android,名字,包名什么的随便取。一路下一步,生成之后,在默认生成的Activity的layout的TextView上加一个id。(这个都会吧)android:id="@+id/hello_jni"。此时的layout文件内容如下:

<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context=".MainActivity"><TextViewandroid:id="@+id/hello_jni"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/hello_world"/></RelativeLayout>


2.在MainActivity.java中声明native方法。

public native String getHelloJniString();
3.在OnCreate()方法中获取TextView,并设置text。
((TextView)findViewById(R.id.hello_jni)).setText(getHelloJniString());
经过2、3两步之后的MainActivity.java文件内容如下:

packagecom.example.hellojni;importandroid.app.Activity;importandroid.os.Bundle;importandroid.view.Menu;importandroid.widget.TextView;publicclassMainActivityextendsActivity{publicnativeStringgetHelloJniString();@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);((TextView)findViewById(R.id.hello_jni)).setText(getHelloJniString());}@OverridepublicbooleanonCreateOptionsMenu(Menumenu){getMenuInflater().inflate(R.menu.main,menu);returntrue;}}


二。生成.h头文件,编写.c文件。

这一步,你需要C/C++的语言基础。(这个简单的例子只需要简单的。)
按照大多数博客,会告诉你:编译工程之后,进入工程目录文件夹下,在控制台运行
javah -classpathbin/classes -d jni com.example.hellojni.MainAcitivity
,然后就会在工程目录下生成一个jni文件夹,里面就会有.h的头文件了。

实际上,你会遇到一个错误:


错误: 无法访问android.app.Activity
找不到android.app.Activity的类文件

是的,大多数人都会遇到这个问题,我对此表示疑问:那些写博客的人都自己试过没有?

怎么办呢?
1. 有人提出方法,在工程目录下运行命令:
javah -classpathsrc -d jni com.example.hellojni.MainAcitivity
就OK了。是的,这个是OK的。(这个命令和上面一个命令的区别就是 -classpath 不同了。)

2.还有一种方法:在工程目录下,上述命令中加上android.jar的classpath。也是可行的。也就是运行如下命令:javah -classpath F:\JNI\env\platforms\android-17\android.jar;bin/classes -d jni com.example.hellojni.MainActivity
这个命令,就是把android.jar的路径加了进去。这样,就能找到Activity类了。




以上两种可行的得到.h头文件的方法,生成的.h文件的内容是不一样的,你可以试试看。至于哪一种比较好,我目前还不清楚。因为看谷歌NDK的samples里面(samples这个文件夹,就是NDK的示例程序目录,对我们来说,就是教程了)的头文件,似乎是第一种方式。第二种方式倒是没有见到过。
我个人还是倾向于用第二种方式,虽然命令比较烦。。

头文件生成好了,刷新一下工程,就会看到如下的目录结构:

多了一个jni文件夹和里面的一长串名字的头文件。名字太长,我们改短一点,改成HelloJni.h吧。省的麻烦。

接下来编写.c的实现文件。在jni文件夹右击,选择file,命名文件名字为HelloJni.c。确定。也就是如下:

然后打开新建的HelloJni.c文件,输入如下语句并保存:

#include<stdio.h>#include"HelloJni.h"jstringJava_com_example_hellojni_MainActivity_getHelloJniString(JNIEnv*env,jobjectclazz){return(*env)->NewStringUTF(env,"HelloJni!");}


三。编写mk文件,使用Cygwin编译出so文件。

下面开始编写mk文件。在jni目录下创建一个Android.mk的文件(A要大写哦!!不然编译会出错:

AndroidNDK:YourAPP_BUILD_SCRIPTpointstoanunknownfile:./jni/Android.mk/home/aditya/android-ndk-r9/build/core/add-application.mk:176:***AndroidNDK:Aborting....


)。加入如下代码并保存(里面的一些命令先不了解也是可以的。):

LOCAL_PATH:=$(callmy-dir)include$(CLEAR_VARS)LOCAL_MODULE:=HelloJniLOCAL_SRC_FILES:=HelloJni.cinclude$(BUILD_SHARED_LIBRARY)

这里,主要注意两个地方:
LOCAL_MODULE := HelloJni 。这里的HelloJni就是你的库的名字,也就是你loadLibrary的字符串。生成出来的库是libHelloJni.so。
LOCAL_SRC_FILES := HelloJni.c 。这里的HelloJni.c就是c文件的名字。

下面打开Cygwin,进入到工程目录下,输入如下命令,并回车:

$NDK/ndk-build
出现如下画面,就说明ok了。

然后我们刷新工程,会发现,多了一个obj文件夹,和libs文件夹里面多了armeabi文件夹和里面的libHelloJni.so库。obj文件夹是没有用的,可以删掉了。

四。加载so文件,运行程序。

最后一步,我们再次进入MainActivity,加载库文件。加入后的代码如下:

packagecom.example.hellojni;importandroid.app.Activity;importandroid.os.Bundle;importandroid.view.Menu;importandroid.widget.TextView;publicclassMainActivityextendsActivity{static{System.loadLibrary("HelloJni");}publicnativeStringgetHelloJniString();@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);((TextView)findViewById(R.id.hello_jni)).setText(getHelloJniString());}@OverridepublicbooleanonCreateOptionsMenu(Menumenu){getMenuInflater().inflate(R.menu.main,menu);returntrue;}}

System.loadLibrary("HelloJni"); 这个字符串就是我们在mk文件中写的LOCAL_MODULE的值。

好了,至此,我们编码ok了。运行起来吧。

更多相关文章

  1. 在Mac和Window上配置android自动打包
  2. android使用html+javascript来制作页面
  3. android中创建XML
  4. Android中xml文件的解析
  5. Android(安卓)自定义控件之第二讲:TypedArray 详解
  6. android studio *.jar 与 *.aar 的生成与*.aar导入项目方法
  7. 如何让android应用程序用中文显示(应用程序名称本地化)
  8. Android应用开发学习笔记之菜单
  9. android Shape Drawable美化圆角图形

随机推荐

  1. 移植dlib到android
  2. Android(安卓)Activity设置全屏
  3. 移植dlib到android
  4. Android(安卓)基于4G模块 GPS定位
  5. 获取Android应用程序的签名
  6. Android实现振动效果
  7. Android(安卓)ListView的子项的随意拖动
  8. android很简单的天气预报例子和XML解析
  9. android定时器应用
  10. 【笔记】android捕获触摸事件