C++学习(二五九)Android Studio如何调试JNI

Posted hankern

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++学习(二五九)Android Studio如何调试JNI相关的知识,希望对你有一定的参考价值。

Debug type选择native

 

 

将app下的build.gradle修改如下:

import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    buildToolsVersion "28.0.3"

    defaultConfig {
        applicationId "osg.AndroidExample"
        minSdkVersion 28
        targetSdkVersion 28

        ndk {
            moduleName "osgNativeLib"
            abiFilters("arm64-v8a")
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }



    externalNativeBuild {
        ndkBuild {
            //path file('../../osgAndroidExampleGLES2/jni/Android.mk')
            path file('src/main/jni/Android.mk')
        }
    }

    sourceSets.main{
        jniLibs.srcDir 'src/main/libs'
        jni.srcDirs = []
    }
    task ndkBuild(type: Exec) {
        if (Os.isFamily(Os.FAMILY_WINDOWS)) {
            //commandLine 'ndk-build.cmd', '-C', file('src/main/jni').absolutePath
            //commandLine 'D:\\\\android-ndk-r16b\\\\ndk-build.cmd', '-C', file('src/main/jni').absolutePath
            commandLine 'D:\\\\android-ndk-r19c\\\\ndk-build.cmd', '-C', file('src/main/jni').absolutePath
            //commandLine 'D:\\\\android-ndk-r20b\\\\ndk-build.cmd', '-C', file('src/main/jni').absolutePath
            //commandLine 'D:\\\\android-ndk-r22\\\\ndk-build.cmd', '-C', file('src/main/jni').absolutePath
            //commandLine 'D:\\\\android-sdk-windows\\\\ndk\\\\22.1.7171670\\\\ndk-build.cmd', '-C', file('src/main/jni').absolutePath

        } else {
            commandLine 'ndk-build', '-C', file('src/main/jni').absolutePath
        }
    }

    tasks.withType(JavaCompile) {
        compileTask -> compileTask.dependsOn ndkBuild
    }


}

jniLibs.srcDir 'src/main/libs':意思是编译成功的so,会存放在src/main/libs目录下面
jni.srcDirs = []:将gradle的jni源目录设置为空,禁用gradle自带的ndk编译
ndkBuild函数的意思是执行默认的ndk编译
task.withType的意思是添加ndkbuild为工程编译的依赖项
因为涉及到os辨认,所以在此文件的文件头需要加入import org.apache.tools.ant.taskdefs.condition.Os 

 

提示错误:

1、executing external native build for ndkBuild android.mk

android.mk文件有错误,需要修改该文件

2、ndk-build.cmd finished with non-zero exit value 2

更换项目一样的NDK版本   https://blog.csdn.net/Alex_yuan666/article/details/83791670

执行命令发现如下错误:D:\\android-ndk-r19c\\ndk-build.cmd -C E:\\Projects\\AndroidStudio\\osgAndroidExampleGLES21\\app\\src\\main\\jni

C:\\Users\\admin>D:\\android-ndk-r19c\\ndk-build.cmd -C E:\\Projects\\AndroidStudio\\osgAndroidExampleGLES21\\app\\src\\main\\jni
Android NDK: WARNING: APP_PLATFORM android-28 is higher than android:minSdkVersion 1 in E:/Projects/AndroidStudio/osgAndroidExampleGLES21/app/src/main/AndroidManifest.xml. NDK binaries will *not* be compatible with devices older than android-28. See https://android.googlesource.com/platform/ndk/+/master/docs/user/common_problems.md for more information.
Android NDK: WARNING:E:/Projects/AndroidStudio/osgAndroidExampleGLES21/app/src/main/jni/Android.mk:osgNativeLib: non-system libraries in linker flags: -losgdb_dds -losgdb_openflight -losgdb_tga -losgdb_rgb -losgdb_osgterrain -losgdb_osg -losgdb_ive -losgdb_deprecated_osgviewer -losgdb_deprecated_osgvolume -losgdb_deprecated_osgtext -losgdb_deprecated_osgterrain -losgdb_deprecated_osgsim -losgdb_deprecated_osgshadow -losgdb_deprecated_osgparticle -losgdb_deprecated_osgfx -losgdb_deprecated_osganimation -losgdb_deprecated_osg -losgdb_serializers_osgvolume -losgdb_serializers_osgtext -losgdb_serializers_osgterrain -losgdb_serializers_osgsim -losgdb_serializers_osgshadow -losgdb_serializers_osgparticle -losgdb_serializers_osgmanipulator -losgdb_serializers_osgfx -losgdb_serializers_osganimation -losgdb_serializers_osg -losgViewer -losgVolume -losgTerrain -losgText -losgShadow -losgSim -losgParticle -losgManipulator -losgGA -losgFX -losgDB -losgAnimation -losgUtil -losg -lOpenThreads
Android NDK:     This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES
Android NDK:     or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
Android NDK:     current module
make: Entering directory `E:/Projects/AndroidStudio/osgAndroidExampleGLES21/app/src/main/jni'
[arm64-v8a] Compile++      : osgNativeLib <= osgNativeLib.cpp
E:/Projects/AndroidStudio/osgAndroidExampleGLES21/app/src/main/jni/osgNativeLib.cpp:5:10: fatal error: 'iostream' file
      not found
#include <iostream>
         ^~~~~~~~~~
1 error generated.
make: *** [E:/Projects/AndroidStudio/osgAndroidExampleGLES21/app/src/main/obj/local/arm64-v8a/objs/osgNativeLib/osgNativeLib.o] Error 1
make: Leaving directory `E:/Projects/AndroidStudio/osgAndroidExampleGLES21/app/src/main/jni'

 

3、ERROR: Could not find com.android.tools.build:gradle:3.5.2.

修改build.gradle文件,将jcenter注释掉,添加三个maven

repositories {
        //jcenter()
        maven { url 'https://maven.aliyun.com/repository/google' }
        maven { url 'https://maven.aliyun.com/repository/jcenter' }
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
    }

4、iostream file not found

Application.mk出现问题,将

APP_STL 		:= gnustl_static

取消注释,并改为

APP_STL 		:= c++_static

5、gnustl_static is no longer supported

由于 Android OS 放弃GCC转向了 Clang 编译器, 所以 NDK 将移除GCC, 所以建议用Clang编译你的程序。参考4的解决方案。

6、Try using LOCAL_STATIC_LIBRARIES or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the current module

将LOCAL_LDFLAGS换成LOCAL_STATIC_LIBRARIES。

7、undefined reference to `__cxa_bad_typeid'

D:/OSG_OSGEARTH_Android/lib64/osgPlugins-3.6.3\\libosgdb_openflight.a(AncillaryRecords.cpp.o): In function `void osg::Object::setUserValue<short>(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&, short const&)':
E:/Projects/QT5.12/osg_earth_src/osg/osg3.6/include\\osg/ValueObject:392: undefined reference to `__cxa_bad_typeid'

混用了no-RTTI代码和RTTI代码

项目中我们自己写的程序必须开启RTTI,而我们使用的外部的一个库使用no-RTTI编译。我们在自己的代码中需要重载一个外部库中的带虚函数的类,结果链接的时候就出现了问题。外部库中的基类使用-fno-rtti选项编译,生成的代码没有typeinfo信息,而我们的代码使用-frtti选项编译,要求基类必须要有typeinfo信息。

 

 

以上是关于C++学习(二五九)Android Studio如何调试JNI的主要内容,如果未能解决你的问题,请参考以下文章

C++学习(三二五)Qt和Android Studio调试区别

C++学习(二五六)CMakelist.txt和Android.mk

C++学习(二五五)HAXM是什么

C++学习(四五九)pe elf coff

C++学习(三五九)GNU构建系统Autotools(autoconf automake libtool autoscan autoheader aclocal automake m4)

C++学习(二五四)自然语言工具