android的ndk学习(1)

  之前学了一段时间ndk,总认为要总结一下。ndk使得很方便地实现java和C与C++代码的相互沟通。合理地掌握使用ndk能够提高应用程序的运行效率。所以对于学习anndroid开发的人来说,ndk是必须掌握的工具。刚刚開始学习的时候是有点兴奋。有点害怕的,兴奋是由于之前学过C++语言。能将学过的东西结合在一起,感觉能够做出更好的东西,害怕的是之前听身边的大神说ndk在android开发中是很难的内容之中的一个。可是无论怎么说我还是找了本书,看了视频,找了一些电子资料,而且開始了学习ndk之路!

一,第一个程序Hello world

   相对来说,使用ndk实现大量的原生方法并让他们与Java类同步非常easy成为一个繁琐的任务。

首先须要新建一个android项目。然后在主函数那里声明一个native方法,代码例如以下

  1. public class MainActivity extends Activity {
  2.  
  3. public static native String test();
  4.  
  5. @Override
  6. protected void onCreate(Bundle savedInstanceState) {
  7. super.onCreate(savedInstanceState);
  8. setContentView(R.layout.activity_main);
  9.  
  10. }

然后使用命令行,開始-cmd,切换到项目的src文件夹下再运行命令例如以下:

  1. javah -d ../jni 包名.MainActivity

这时候刷新项目就会发现多了一个jni目录,里面有个.h的文件,打开就是一个c头文件

  1. /* DO NOT EDIT THIS FILE - it is machine generated */
  2. #include <jni.h>
  3. /* Header for class com_example_exercise_MainActivity */
  4.  
  5. #ifndef _Included_com_example_exercise_MainActivity
  6. #define _Included_com_example_exercise_MainActivity
  7. #ifdef __cplusplus
  8. extern "C" {
  9. #endif
  10. #undef com_example_exercise_MainActivity_MODE_PRIVATE
  11. #define com_example_exercise_MainActivity_MODE_PRIVATE 0L
  12. #undef com_example_exercise_MainActivity_MODE_WORLD_READABLE
  13. #define com_example_exercise_MainActivity_MODE_WORLD_READABLE 1L
  14. #undef com_example_exercise_MainActivity_MODE_WORLD_WRITEABLE
  15. #define com_example_exercise_MainActivity_MODE_WORLD_WRITEABLE 2L
  16. #undef com_example_exercise_MainActivity_MODE_APPEND
  17. #define com_example_exercise_MainActivity_MODE_APPEND 32768L
  18. #undef com_example_exercise_MainActivity_MODE_MULTI_PROCESS
  19. #define com_example_exercise_MainActivity_MODE_MULTI_PROCESS 4L
  20. #undef com_example_exercise_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING
  21. #define com_example_exercise_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L
  22. #undef com_example_exercise_MainActivity_BIND_AUTO_CREATE
  23. #define com_example_exercise_MainActivity_BIND_AUTO_CREATE 1L
  24. #undef com_example_exercise_MainActivity_BIND_DEBUG_UNBIND
  25. #define com_example_exercise_MainActivity_BIND_DEBUG_UNBIND 2L
  26. #undef com_example_exercise_MainActivity_BIND_NOT_FOREGROUND
  27. #define com_example_exercise_MainActivity_BIND_NOT_FOREGROUND 4L
  28. #undef com_example_exercise_MainActivity_BIND_ABOVE_CLIENT
  29. #define com_example_exercise_MainActivity_BIND_ABOVE_CLIENT 8L
  30. #undef com_example_exercise_MainActivity_BIND_ALLOW_OOM_MANAGEMENT
  31. #define com_example_exercise_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
  32. #undef com_example_exercise_MainActivity_BIND_WAIVE_PRIORITY
  33. #define com_example_exercise_MainActivity_BIND_WAIVE_PRIORITY 32L
  34. #undef com_example_exercise_MainActivity_BIND_IMPORTANT
  35. #define com_example_exercise_MainActivity_BIND_IMPORTANT 64L
  36. #undef com_example_exercise_MainActivity_BIND_ADJUST_WITH_ACTIVITY
  37. #define com_example_exercise_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L
  38. #undef com_example_exercise_MainActivity_CONTEXT_INCLUDE_CODE
  39. #define com_example_exercise_MainActivity_CONTEXT_INCLUDE_CODE 1L
  40. #undef com_example_exercise_MainActivity_CONTEXT_IGNORE_SECURITY
  41. #define com_example_exercise_MainActivity_CONTEXT_IGNORE_SECURITY 2L
  42. #undef com_example_exercise_MainActivity_CONTEXT_RESTRICTED
  43. #define com_example_exercise_MainActivity_CONTEXT_RESTRICTED 4L
  44. #undef com_example_exercise_MainActivity_RESULT_CANCELED
  45. #define com_example_exercise_MainActivity_RESULT_CANCELED 0L
  46. #undef com_example_exercise_MainActivity_RESULT_OK
  47. #define com_example_exercise_MainActivity_RESULT_OK -1L
  48. #undef com_example_exercise_MainActivity_RESULT_FIRST_USER
  49. #define com_example_exercise_MainActivity_RESULT_FIRST_USER 1L
  50. #undef com_example_exercise_MainActivity_DEFAULT_KEYS_DISABLE
  51. #define com_example_exercise_MainActivity_DEFAULT_KEYS_DISABLE 0L
  52. #undef com_example_exercise_MainActivity_DEFAULT_KEYS_DIALER
  53. #define com_example_exercise_MainActivity_DEFAULT_KEYS_DIALER 1L
  54. #undef com_example_exercise_MainActivity_DEFAULT_KEYS_SHORTCUT
  55. #define com_example_exercise_MainActivity_DEFAULT_KEYS_SHORTCUT 2L
  56. #undef com_example_exercise_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL
  57. #define com_example_exercise_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
  58. #undef com_example_exercise_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL
  59. #define com_example_exercise_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
  60. /*
  61. * Class: com_example_exercise_MainActivity
  62. * Method: test
  63. * Signature: ()Ljava/lang/String;
  64. */
  65. JNIEXPORT jstring JNICALL Java_com_example_exercise_MainActivity_test
  66. (JNIEnv *, jclass);
  67.  
  68. /*
  69. * Class: com_example_exercise_MainActivity
  70. * Method: updateFile
  71. * Signature: (Ljava/lang/String;)V
  72. */
  73. <pre name="code" class="java">JNICALL Java_com_example_exercise_MainActivity_updateFile
  74. (JNIEnv *, jclass, jstring)

#ifdef __cplusplus}#endif#endif

  1.  

代码非常长。可是我们临时仅仅要看

  1. JNICALL Java_com_example_exercise_MainActivity_updateFile
  2. (JNIEnv *, jclass, jstring)

这就是依据我们一開始在mainactivity定义的那个native方法生成的一个方法。

有了头文件,我们就能够開始写.c文件了。即实现文件,新建一个文件main.c。然后输入代码例如以下

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. JNIEXPORT jstring JNICALL Java_com_example_exercise_MainActivity_test
  4. (JNIEnv * env, jobject obj){
  5.  
  6. return (*env)->NewStringUTF(env, "Hello world !");
  7. }

返回一个字符串,这就是java与c交互的代码。

可是如今还不能直接执行,还要新建一个android.mk文件对项目进行配置,代码例如以下:
  1. LOCAL_PATH :=$(call my-dir)
  2.  
  3. include $(CLEAR_VARS)
  4. LOCAL_MODULE := main
  5. LOCAL_SRC_FILES := main.c
  6. include $(BUILD_SHARED_LIBRARY)

好了,然后就是在mainactivity中用法了。代码例如以下

  1. public class MainActivity extends Activity {
  2.  
  3. public static native String test();
  4.  
  5. @Override
  6. protected void onCreate(Bundle savedInstanceState) {
  7. super.onCreate(savedInstanceState);
  8. setContentView(R.layout.activity_main);
  9. TextView t = (TextView)findViewById(R.id.jnitextview);
  10. t.setText(test());
  11.  
  12. }
  13. static {
  14. System.loadLibrary("main");
  15. }
  16.  
  17. }

导入库是使用的

  1. static {
  2. System.loadLibrary("main");
  3. }

main是我们在android.mk中配置的一个名字,如今万事俱备,仅仅差编译生成so文件了。我们打开cmd而且切换到项目的文件夹下,执行ndk-build。中间是减号,不是下划线,刷新项目就能够看到libs中多了个文件夹和里面的一个libmain.so文件,这时候就能够执行项目了!

假设没有意外就会出现helloworld在手机频幕上。

二。打印log

打印log是必须掌握的仅仅是。所以这里介绍一下怎么配置,首先是配置android.mk文件。加入一行代码

LOCAL_LDLIBS    += -llog
完整的android.mk代码例如以下
  1. LOCAL_PATH :=$(call my-dir)
  2.  
  3. include $(CLEAR_VARS)
  4. LOCAL_MODULE := main
  5. LOCAL_SRC_FILES := main.c
  6. LOCAL_LDLIBS += -llog
  7. include $(BUILD_SHARED_LIBRARY)

然后在实现文件里加入头文件#include<android/log.h>

而且宏定义要打印log的类型
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))

#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__))
在代码中使用LOGI()或者LOGW。执行程序,然后就能够打印log了!更加具体的能够去看java api文档中的ndk篇。

三,总结

刚開始学jni,要配置这个要配置那个的很麻烦,可是写了一个helloworld以后感觉配置也就那样,万事开头难啊!相信后面的学习会越来越难。可是也会越来越有意思,希望继续加油!

android的ndk学习(1)的更多相关文章

  1. Android Studio NDK 学习之接受Java传入的字符串

    本博客是基于Android Studio 1.3 preview版本,且默认你已经安装了Android SDK, Android NDK. 用Android Studio新建一个工程叫Prompt,其 ...

  2. Android Studio NDK 学习之接受Java传入的Int数组

    本博客是基于Android Studio 1.3 preview版本,且默认你已经安装了Android SDK, Android NDK. 用Android Studio新建一个工程叫AndroidJ ...

  3. android的JNI 、 NDK 学习!

    转载的! Java Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) ...

  4. Android JNI和NDK学习(04)--NDK调试方法(转)

    本文转自:http://www.cnblogs.com/skywang12345/archive/2013/05/23/3092812.html 本文主要介绍在ndk中添加log的方法.然后,我们就可 ...

  5. Android JNI和NDK学习(03)--动态方式实现JNI(转)

    本文转自:http://www.cnblogs.com/skywang12345/archive/2013/05/23/3092491.html 前面总结了静态实现JNI的方法,本文介绍如何动态实现J ...

  6. Android JNI和NDK学习(01)--搭建NDK开发环境(转)

    本文转自:http://www.cnblogs.com/skywang12345/archive/2013/05/23/3095013.html 本文主要介绍“JNI”.“Android NDK”以及 ...

  7. Android之NDK开发(转)

    Android之NDK开发 一.NDK产生的背景 Android平台从诞生起,就已经支持C.C++开发.众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第 ...

  8. ndk学习20: jni之OnLoad动态注册函数

    一.原理 当在系统中调用System.loadLibrary函数时,该函数会找到对应的动态库, 然后首先试图找到"JNI_OnLoad"函数,如果该函数存在,则调用它 JNI_On ...

  9. NDK学习4: Eclipse HelloWorld

    NDK学习4: Eclipse HelloWorld 1.配置Eclipse NDK环境  Window->preferences->android->ndk   2.新建Andro ...

随机推荐

  1. eclipse自动为变量生成Get/Set函数

    启动Eclipse,打开demo工程.如图:   假定为成员变量test生成Get/Set函数. 光标定位到该成员变量,如图:   右键选择“source”-“Generate Getters and ...

  2. 边框带阴影 box-shadow

    .chosen-container-active .chosen-single { border: 1px solid #5897fb; -webkit-box-shadow: 0 0 5px rgb ...

  3. CAD绘制固定圆形标注(网页版)

    js中实现代码说明: function DoFixCircleComment() { var ent = mxOcx.DrawCustomEntity("TestMxCustomEntity ...

  4. java_线程的通信

    线程的通信共有三个方法: wait()运行时阻塞,释放锁 notify()唤醒阻塞线程 notifll()唤醒全部阻塞线程 public class ThreadTest01 { public sta ...

  5. java_线程分类

    线程分为守护线程和用户线程,如java虚拟机的回收机制就是守护线程,线程开始运行它就启动,线程结束它就结束 用户线程变守护线程:Thread(线程).setDaemon(true)

  6. std::function和std::bind详解

    原文:https://blog.csdn.net/xiaoyink/article/details/79348806

  7. POJ 1664 放苹果( 递推关系 )

    链接:传送门 思路:苹果m个,盘子n个.假设 f ( m , n ) 代表 m 个苹果,n个盘子有 f ( m , n ) 种放法. 根据 n 和 m 的关系可以进一步分析: 特殊的 n = 1 || ...

  8. ubuntu 16.04 数据库mysql安装与管理

    1.安装mysql的客户端与服务器端 $>sudo apt-get install mysql-server mysql-client 2.管理服务 1.启动 $>sudo service ...

  9. CentOS6.5下编译安装LAMP环境

    LAMP(Linux-Apache-MySQL-PHP)网站架构是目前国际流行的Web框架.该框架能够满足大流量.大并发量的网站需求:当然.也可以直接使用高性能的服务器.高性能的负载均衡硬件以及CDN ...

  10. Python 3安装体验篇(win10)

    一.下载 1.打开官网https://www.python.org/downloads/windows/,点击Python 3版本链接 2.点击win10 64位安装链接,即可下载Python安装 二 ...