zoukankan      html  css  js  c++  java
  • Android Studio开发JNIproject

    使用Android Sutdio创建一个新的project后,接下来记录创建NDKproject的基本步骤。

    本文将达到:
    1. 创建NDKproject
    2. 在JNI中输出Log语句
    3. 指定编译的so库的abi版本号
    4. 解决在创建NDKproject中的问题

    Step: 1. 加入native接口
    注意写好native接口和System.loadLibrary()就可以了。并无特别之处。
    P.S:onCreate()中对R.id.txt运行setText()。所以这里须要对xml布局文件按正常的开发步骤进行改动就可以。

    直接给出代码例如以下:
    public class MainActivity extends Activity{
        static {
            System.loadLibrary("JniTest");
        }
       
        public native String getStringFromNative();
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            TextView txtView = (TextView) findViewById(R.id.txt);
            txtView.setText(getStringFromNative());
        }
    }



    Step: 2.运行Build->Make Project


    这一步骤运行一下,验证project中并无其他错误,并对project进行了编译,生成了.class文件.
    .class文件的生成路径是在 app_path/build/intermediates/classes/debug下的.例如以下图:


    Step: 3.javah生成c头文件

    点击"View->Tool Windows->Terminal",即在Studio中进行终端命令行工具.运行例如以下命令生成c语言头文件。
    这里须要注意的是要进入 <Project>appsrcmain的文件夹下运行javah命令,为的是生成的 .h 文件相同是在<Project>appsrcmain路径下,能够在Studio的project结构中直接看到。


    操作命令:
    javah -d jni -classpath <SDK_android.jar>;<APP_classes> lab.sodino.jnitest.MainActivity
    详细操作图例如以下:

    javah -d jni -classpath c:UserssodinochenAppDataLocalAndroidsdkplatforms
    android-16android.jar;....uildintermediatesclassesdebug lab.sodino.jnitest.MainActivity


    对于"主版本号51比50新,此编译器支持最新的主版本号"则是因为电脑上安装了两个版本号的jdk引起的,而当前使用的是旧的jdk。
    把旧的jdk删除。并运行java version命令后显示当前jdk为最新的1.7时,则不会再有此提示了。例如以下图:

    最后的生成结果:




    Step: 4.编辑c文件

    在main.c文件里实现头文件里的方法,详细功能为直接return回一个String。而且使用android_log打印出相关日志。

    代码例如以下:
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    #include <android/log.h>
    
    #ifndef LOG_TAG
    #define LOG_TAG "ANDROID_LAB"
    #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
    #endif
    
    /* Header for class lab_sodino_jnitest_MainActivity */
    
    #ifndef _Included_lab_sodino_jnitest_MainActivity
    #define _Included_lab_sodino_jnitest_MainActivity
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class: lab_sodino_jnitest_MainActivity
     * Method: getStringFromNative
     * Signature: ()Ljava/lang/String;
     */
    JNIEXPORT jstring JNICALL Java_lab_sodino_jnitest_MainActivity_getStringFromNative
      (JNIEnv * env, jobject jObj){
          LOGE("log string from ndk.");
          return (*env)->NewStringUTF(env,"Hello From JNI!");
      }
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    

    到这里后。我们再运行一个"Build->Make Project"。发现"Messages Gradle Build"会给出提演示样例如以下:
    Error:Execution failed for task ':app:compileDebugNdk'. 
    > NDK not configured. 
    Download the NDK from http://developer.android.com/tools/sdk/ndk/.Then add ndk.dir=path/to/ndk in local.properties. 
    (On Windows, make sure you escape backslashes, e.g. C:\ndk rather than C:
    dk)
    这里提示了NDK未配置,而且须要在project中的local.properties文件里配置NDK路径。

    好了,提示非常清楚了。那我们就进入下一步吧。



    Step: 5.配置NDK
    这一步包含两个动作:
    1.指明ndk路径

    2. 改动build.gradle配置
        project中共同拥有两个build.gradle配置文件。我们要改动的是在<Project>appuild.gradle这个文件。为其在defaultConfig分支中添加上
        ndk {
            moduleName "JniTest"
            ldLibs "log", "z", "m"
            abiFilters "armeabi", "armeabi-v7a", "x86"
        }
        以上配置代码指定的so库名称为JniTest,链接时使用到的库。相应android.mk文件里的LOCAL_LDLIBS。及终于输出指定三种abi体系结构下的so库。
    加入后例如以下图:

    这时,再运行"Build->Rebuild Project",就能够编译出so文件了。
    但在Window平台上会出现一个问题:
    Error:Execution failed for task ':app:compileDebugNdk'.
    > com.android.ide.common.internal.LoggedErrorException: Failed to run command:
     D:Missionadt-bundle-windows
    dk-r10b
    dk-build.cmd NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=C:UserssodinochenAndroidstudioProjectsJniTest2appuildintermediates
    dkdebugAndroid.mk APP_PLATFORM=android-21 NDK_OUT=C:UserssodinochenAndroidstudioProjectsJniTest2appuildintermediates
    dkdebugobj NDK_LIBS_OUT=C:UserssodinochenAndroidstudioProjectsJniTest2appuildintermediates
    dkdebuglib APP_ABI=armeabi,armeabi-v7a,x86
    Error Code:
     2
    Output:
     make.exe: *** No rule to make target `C:UserssodinochenAndroidstudioProjectsJniTest2appuildintermediates
    dkdebugobj/local/armeabi/objs/JniTest/C_UserssodinochenAndroidstudioProjectsJniTest2appsrcmainjni', needed by `C:UserssodinochenAndroidstudioProjectsJniTest2appuildintermediates
    dkdebugobj/local/armeabi/objs/JniTest/C_UserssodinochenAndroidstudioProjectsJniTest2appsrcmainjnimain.o'. Stop.
    出现这个错误非常莫名其妙..几番折腾下,找到一个视频出来了大概原因及解决方案:
    出处见Youtube视频 02:50分開始:https://www.youtube.com/watch?

    v=okLKfxfbz40#t=362

    在Windows下NDK一个bug,当只编译一个文件时出现会出现此问题,解决方法就是再往jni文件夹加入一个空util.c文件就可以。例如以下图:


    编译出来的库文件被Studio输出到了下图的路径中




    Step: 6.安装运行

    界面:


    查看Log打印:


  • 相关阅读:
    JS实现右侧悬浮框随着页面的上下轮动而移动
    js实现一个简单的时钟表
    js实现前后端分离点击新闻列表跳转到相应的详情页
    获取当前时间的年、月、日
    点击获取今天时间、明天时间、本周时间、本月时间
    判断是不是ie7浏览器,把https换成http(兼容ie7)
    jq控制class相同点击隐藏当前相同的父元素
    js、jq控制class相同当子元素为空时,父元素隐藏
    photoshop
    不得不说一下vite
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5371507.html
Copyright © 2011-2022 走看看