Android NDK开发之入门教程

        JNI(Java Native Interface, Java本地化方法)使得Java能与其它语言(如C、C++)的动态库进行交互。

        在Android 项目中,经常看到地图,统计,推送之类的第三方平台都用了 JNI。

        Android NDK(Android Native Development Kit)是一系列的开发工具,使用JNI编程,可以提高程序的执行效率,更方便地使用现存的开源库。

        至于配置NDK环境,无论是Cygwin还是最新的(无Cygwin),网上的教程太多了,这里不再赘述。

        好了,下面开始写一个入门Demo了……


        首先新建一个Android project
        项目右键点击-Android Tools -Add Native Support
        点击Finish。



        可以看到在Android项目中生成了一个JNI文件:


        然后在MainActivity 中添加以下代码:

public class MainActivity extends ActionBarActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		initJNI();
	}

	private void initJNI() {

		TextView tv = new TextView(this);
		tv.setTextSize(25);
		tv.setBackgroundColor(Color.parseColor("#FFA07A"));
		tv.setText(myTestNdk());
		tv.setGravity(Gravity.CENTER);
		setContentView(tv);

	}

	public native String myTestNdk();

	static {
		System.loadLibrary("TestBaseJNI");
	}
}

  • System.loadLibrary("TestBaseJNI")表示VM去加载动态库TestBaseJNI.so文件;
  • public native String myTestNdk(),这里的native表示这个方法由本地代码定义,需要通过jni接口调用本地c/c++代码,在java代码中仅仅是声明。

        然后在TestBaseJNI.cpp添加以下代码:

#include <string.h>
#include <jni.h>

extern "C" {

jstring Java_com_example_testbase_MainActivity_myTestNdk(JNIEnv* env,
		jobject thiz) {
	return env->NewStringUTF("Hello NDK");
}

}

  • 声明加extern "C",是解决C++函数名问题;
  • "Java_com_example_testbase_MainActivity_myTestNdk",严格按照这种格式写。开头是Java,后面依次是包名,Activity名,方法名;
  • jstring表示返回类型,这段函数的功能就是返回字符串"Hello NDK"。

 这时候可能会报错。
        Type 'jstring' could not be resolved
        Method 'NewStringUTF' could not be resolved等等。
遇到这些类错误:

        Type 'XXX' could not be resolved

        Method  'XXX' ' could not be resolved

常见的解决办法:

  • 右键->Properties,点击C/C++ General展开,点击Path and Symbols, 右侧Includes,点击Add,把NDK文件夹下的jni头文件和相应的C++头文件添加进来


这是我添加的两个路径:
        F:\Installer\Programming\android-ndk32-r10b-windows-x86\android-ndk-r10b\toolchains\mipsel-linux-android-4.8\prebuilt\windows\lib\gcc\mipsel-linux-android\4.8\include
        F:\Installer\Programming\android-ndk32-r10b-windows-x86\android-ndk-r10b\platforms\android-19\arch-arm\usr\include

运行成功界面:



        好了,我们再通过手动建JNI的方式来实现上面的Demo

  • 首先新建一个Android project
  • 根目录建立JNI文件夹,再分别创建Android.mk和hello-jni.c文件

        MainActivity 中添加以下代码:

public class MainActivity extends ActionBarActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		TextView myTextView = new TextView(this);
		myTextView.setText(stringTestNdk());
		setContentView(myTextView);
	}

	public native String stringTestNdk();

	static {
		System.loadLibrary("hello-jni");
	}
}

        hello-jni.c中添加:

#include <string.h>
#include <jni.h>

/* This is a trivial JNI example where we use a native method
 * to return a new VM String. See the corresponding Java source
 * file located at:
 *
 *   apps/samples/hello-jni/project/src/com/example/hellojni/HelloJni.java
 */

jstring Java_com_example_testndk_MainActivity_stringTestNdk(JNIEnv* env,
		jobject thiz) {
	  return (*env)->NewStringUTF(env, "Hello Test NDK !");
//	return env->NewStringUTF("Hello NDK");
}

        Android.mk配置中添加:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)

LOCAL_MODULE表示编译的动态库名称
LOCAL_SRC_FILES 表示源代码文件

        建立并配置Builder:

  • 右键-属性-Builder-New-Main,Refresh,Build中如下配置(按照实际项目操作,这里只是举例),编译并生成.so文件。



        然后可以看到在在控制台输出信息(如果没有,Project-Clean):

[armeabi] Compile thumb  : hello-jni <= hello-jni.c
[armeabi] SharedLibrary  : libhello-jni.so
[armeabi] Install        : libhello-jni.so => libs/armeabi/libhello-jni.so

        在libs-armeabi下生成了libhello-jni.so文件




        运行成功截图:


        代码就这么几行,注意操作步骤就OK了,Demo就不上传了……

猜你喜欢

转载自blog.csdn.net/yalinfendou/article/details/45030905