• android的ndk学习(1)


    android的ndk学习(1)

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

    一,第一个程序Hello world

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

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

    public class MainActivity extends  Activity {
    
    	public static native String test();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
         
           
        }

    然后使用命令行,開始-cmd,切换到项目的src文件夹下再运行命令例如以下:
    javah -d ../jni 包名.MainActivity
    这时候刷新项目就会发现多了一个jni目录,里面有个.h的文件,打开就是一个c头文件
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_example_exercise_MainActivity */
    
    #ifndef _Included_com_example_exercise_MainActivity
    #define _Included_com_example_exercise_MainActivity
    #ifdef __cplusplus
    extern "C" {
    #endif
    #undef com_example_exercise_MainActivity_MODE_PRIVATE
    #define com_example_exercise_MainActivity_MODE_PRIVATE 0L
    #undef com_example_exercise_MainActivity_MODE_WORLD_READABLE
    #define com_example_exercise_MainActivity_MODE_WORLD_READABLE 1L
    #undef com_example_exercise_MainActivity_MODE_WORLD_WRITEABLE
    #define com_example_exercise_MainActivity_MODE_WORLD_WRITEABLE 2L
    #undef com_example_exercise_MainActivity_MODE_APPEND
    #define com_example_exercise_MainActivity_MODE_APPEND 32768L
    #undef com_example_exercise_MainActivity_MODE_MULTI_PROCESS
    #define com_example_exercise_MainActivity_MODE_MULTI_PROCESS 4L
    #undef com_example_exercise_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING
    #define com_example_exercise_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L
    #undef com_example_exercise_MainActivity_BIND_AUTO_CREATE
    #define com_example_exercise_MainActivity_BIND_AUTO_CREATE 1L
    #undef com_example_exercise_MainActivity_BIND_DEBUG_UNBIND
    #define com_example_exercise_MainActivity_BIND_DEBUG_UNBIND 2L
    #undef com_example_exercise_MainActivity_BIND_NOT_FOREGROUND
    #define com_example_exercise_MainActivity_BIND_NOT_FOREGROUND 4L
    #undef com_example_exercise_MainActivity_BIND_ABOVE_CLIENT
    #define com_example_exercise_MainActivity_BIND_ABOVE_CLIENT 8L
    #undef com_example_exercise_MainActivity_BIND_ALLOW_OOM_MANAGEMENT
    #define com_example_exercise_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
    #undef com_example_exercise_MainActivity_BIND_WAIVE_PRIORITY
    #define com_example_exercise_MainActivity_BIND_WAIVE_PRIORITY 32L
    #undef com_example_exercise_MainActivity_BIND_IMPORTANT
    #define com_example_exercise_MainActivity_BIND_IMPORTANT 64L
    #undef com_example_exercise_MainActivity_BIND_ADJUST_WITH_ACTIVITY
    #define com_example_exercise_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L
    #undef com_example_exercise_MainActivity_CONTEXT_INCLUDE_CODE
    #define com_example_exercise_MainActivity_CONTEXT_INCLUDE_CODE 1L
    #undef com_example_exercise_MainActivity_CONTEXT_IGNORE_SECURITY
    #define com_example_exercise_MainActivity_CONTEXT_IGNORE_SECURITY 2L
    #undef com_example_exercise_MainActivity_CONTEXT_RESTRICTED
    #define com_example_exercise_MainActivity_CONTEXT_RESTRICTED 4L
    #undef com_example_exercise_MainActivity_RESULT_CANCELED
    #define com_example_exercise_MainActivity_RESULT_CANCELED 0L
    #undef com_example_exercise_MainActivity_RESULT_OK
    #define com_example_exercise_MainActivity_RESULT_OK -1L
    #undef com_example_exercise_MainActivity_RESULT_FIRST_USER
    #define com_example_exercise_MainActivity_RESULT_FIRST_USER 1L
    #undef com_example_exercise_MainActivity_DEFAULT_KEYS_DISABLE
    #define com_example_exercise_MainActivity_DEFAULT_KEYS_DISABLE 0L
    #undef com_example_exercise_MainActivity_DEFAULT_KEYS_DIALER
    #define com_example_exercise_MainActivity_DEFAULT_KEYS_DIALER 1L
    #undef com_example_exercise_MainActivity_DEFAULT_KEYS_SHORTCUT
    #define com_example_exercise_MainActivity_DEFAULT_KEYS_SHORTCUT 2L
    #undef com_example_exercise_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL
    #define com_example_exercise_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
    #undef com_example_exercise_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL
    #define com_example_exercise_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
    /*
     * Class:     com_example_exercise_MainActivity
     * Method:    test
     * Signature: ()Ljava/lang/String;
     */
    JNIEXPORT jstring JNICALL Java_com_example_exercise_MainActivity_test
      (JNIEnv *, jclass);
    
    /*
     * Class:     com_example_exercise_MainActivity
     * Method:    updateFile
     * Signature: (Ljava/lang/String;)V
     */
    <pre name="code" class="java">JNICALL Java_com_example_exercise_MainActivity_updateFile
      (JNIEnv *, jclass, jstring)
    #ifdef __cplusplus}#endif#endif
    
    
    代码非常长。可是我们临时仅仅要看
    JNICALL Java_com_example_exercise_MainActivity_updateFile
      (JNIEnv *, jclass, jstring)
    这就是依据我们一開始在mainactivity定义的那个native方法生成的一个方法。

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

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

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

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

    好了,然后就是在mainactivity中用法了。代码例如以下
    public class MainActivity extends  Activity {
    
    	public static native String test();
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            TextView t = (TextView)findViewById(R.id.jnitextview);
            t.setText(test());
           
        }
        static {
    		System.loadLibrary("main");
    	}
    
        
    }

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

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

    二。打印log

    打印log是必须掌握的仅仅是。所以这里介绍一下怎么配置,首先是配置android.mk文件。加入一行代码
    LOCAL_LDLIBS    += -llog
    完整的android.mk代码例如以下
    LOCAL_PATH :=$(call my-dir)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE    := main
    LOCAL_SRC_FILES := main.c
    LOCAL_LDLIBS    += -llog
    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以后感觉配置也就那样,万事开头难啊!相信后面的学习会越来越难。可是也会越来越有意思,希望继续加油!
  • 相关阅读:
    《设计模式》-原则二:里氏代换原则(LSP)
    设计模式从0开始
    net reactor加密源码保软件安全-net reactor使用教程
    python中import和from...import区别
    Python之import
    c#执行bat批处理文件,并通过线程将结果显示在控件中
    C#中双问号、双冒号等几个特殊关键字
    Eclipse debug高级技巧(转)
    Android从零开始--安装
    以另一个用户来运行程序
  • 原文地址:https://www.cnblogs.com/yfceshi/p/6893463.html
Copyright © 2020-2023  润新知