Android studio:第一个NDK项目(新建&导入C++&遇到问题)

Android studio:第一个NDK项目(新建&导入C++&遇到问题)

 

android studio版本:3.4.1                                                                                                   

笔者:Linvest

 

 

目录

1.1、离线下载NDK与CMake(建议使用:离线下载)

1-2、在线下载NDK与CMake(不建议,笔者用android studio 3.4.1版本时,编译出错了)

2-1:创建支持C++的工程(建议先感觉一下,很简单)

 

以下是在java工程中增加C++程序的流程:

2-2、java工程增加c++程序

3、配置build.gradle(APP)

4:创建cpp文件夹、CmakeLists.txt和C++程序:native-lib.cpp

5、在java程序里面加载库、声明C++接口,并调用MainActivity.java代码如下:

6、配置jni调试(详情看:2-1的第5点:配置jni打印)7、效果

后:遇到的困难:


 

 


1.1、离线下载NDK与CMake(建议使用:离线下载)

1)NDK 22.0.7026061(官方),需要用谷歌浏览器 :
https://developer.android.google.cn/ndk/downloads/


2)CMake 3.10.2(已上传,0积分下载),下载解压到sdk路径即可;
https://download.csdn.net/download/Liyunhao_haoge/14927883


1-2、在线下载NDK与CMake(不建议,笔者用android studio 3.4.1版本时,编译出错了)

 

2-1:创建支持C++的工程(建议先感觉一下,很简单)

1)创建工程,选择:native c++,填入工程名,如:CHello,点击finish

 

2)工程会自动编译,笔者编译报错:ERROR: A problem occurred configuring project ':app'.
3)报错如下:

4)解决
下载:ndk
配置ndk的路径:

ndk.dir=E\:\\android-ndk-r21d

配置完别忘记点击:Try Again,编译顺利通过;


5)配置jni打印
(1)配置jni调试使能,打开File -> Project Structure... -> Build Variants中的Jni Debuggable配置成true

 

(2)配置调试类型为Auto,打开Run -> Edit Configurations -> Android App -> app中选择:Debugger
,debugger type
:选择:Auto

 

6)在C++里面打断点,虚拟机跑起来看效果:

 

7)看最终效果

 


以下是在java工程中增加C++程序的流程:


2-2、java工程增加c++程序

有了上面的效果,做起来也有对照了,毕竟笔者也只是刚学了6个月安卓的小白,顺腾摸瓜吧,哈哈,走起;
1)创建一个java工程(如:HelloWorld

2)配置local.properties(笔者的ndk编译C++有问题嘛 -_- )

#ndk.dir=C\:\\android-sdk-windows\\ndk-bundle
ndk.dir=E\:\\android-ndk-r21d
sdk.dir=C\:\\android-sdk-windows

3、配置build.gradle(APP)

注意:这里的CMakeLists.txt路径,要与下面第4步创建CMakeLists.txt的路径一样;

apply plugin: 'com.android.application'

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"
    defaultConfig {
        applicationId "com.example.helloworld"
        minSdkVersion 15
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        externalNativeBuild { //第一处增加
            cmake {
                cppFlags ""
            }
        }
    }

    externalNativeBuild { //第二处增加
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.10.2"
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            jniDebuggable = true
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}

4:创建cpp文件夹、CmakeLists.txt和C++程序:native-lib.cpp

1)cpp文件夹创建:

2)创建CMakeLists.txt,构建cmake与c++的关系,在此文件里面填入c++的文件名即可;

填充内容:

cmake_minimum_required(VERSION 3.4.1)

add_library( # Sets the name of the library.
        #《1、java程序用来加载的库名称》
        native-lib

        SHARED

        #《2、此处填入需要增加的cpp文件》
        native-lib.cpp )

find_library(
        log-lib
        log )

target_link_libraries( # Specifies the target library.
        #3、填入上面所有的库
        native-lib

        ${log-lib} )

 

3)创建C++工程

编写C++代码(native-lib.cpp):

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

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_helloworld_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

 

cmake只是构建makefile编译的时候方便,实则java程序还不知道如何识别C++的接口,于是他们定了一套
规则:
1)C++程序方法的命名遵循:Java_包名_类名_方法名
2)java程序里面需要声明方法,方法名与C++的方法名一致,且需要加载库文件;(java下面讲,此处只
是C++程序)
注意:看C++程序接口的命名带有下划线的,万一你的类名有下划线,或者工程名有下划线,会被坑很长时
间查问题,工程名与类名最好不要加下划线了


5、在java程序里面加载库、声明C++接口,并调用
MainActivity.java代码如下:

package com.example.helloworld;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    //1、加载C++库
    static {
        System.loadLibrary("native-lib");
    }

    //2、使用关键字 native 声明C++接口
    public native String stringFromJNI();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv_hello = findViewById(R.id.tv_hello);
        tv_hello.setText(stringFromJNI());//3、调用即可;
    }
}


6、配置jni调试(详情看:2-1的第5点:配置jni打印)
7、效果


1)打断点调试如下:

2)使用C++接口的效果如下:

后:遇到的困难:

1、用android studio下载的ndk的时候,编译C++的时候,出错了,如下:
解决方案:
下载官网的NDK

2、太纠结experimental插件需要特定的Gradle版本
有些文章写得非常好,提到experimental版本与Gradle版本要一一对应,看了很多的NDK开发和调试文章,
但有些文章根本就没有提到experimental插件版本,后面调通后,都没研究版本问题了,如果知道的教一
下我吧;
3、太纠结LLDB这玩意;(没下载成功,后面没影响调试,也不纠结了)
下载步骤:
1)http://tool.chinaz.com/
    选择ping测试
    输入框输入:dl.google.com
    只要:海外  的就行,会列出很多能ping通的地址;
    使用:cmd命令,ping通了一个,记录下来(我没ping通过国外的,后面放弃,也不影响)
2)C:\Windows\System32\drivers\etc
    编辑:HOSTS
    在最后一行加入ping通的地址,以及要访问的网站,如:
    180.163.151.33 dl-ssl.google.com
4、工程加了下划线导致运行C++时找不到,去掉就没问题了,类名估计也会有问题,没试过;
    

    

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值