首页 > 其他分享 >Android App开发JNI环境配置

Android App开发JNI环境配置

时间:2023-03-15 10:46:48浏览次数:45  
标签:NDK App public Android import JNI app android

因为想写一个native_crash的app做测试,所以搭建一个这样的jni环境。
jni环境配置可以自己写配置文件,也可以使用Android Studio自动生成。下面我们用Android Studio为IDE来进行JNI环境配置
参考文章:Android - JNI环境搭建和简单案例入门

概念

JNI:Java Native Interface。实现java 与本地语言(android是linex系统开发的,语言是c/c++) 的相互调用。
NDK:Native Development Kit。用来模拟另一个平台特性进行编译的工具集合,能够快速开发C(或C++)的动态库,能自动将so和java应用一起打包成apk。

在android的JNI中,要先将相应的C/C++语言打包生成.so文件(c++的函数库),然后导入到lib文件夹中供java调用。
需要的工具:
Android 原生开发工具包 (NDK)
CMake:一款外部构建工具,可与 Gradle 搭配使用来构建原生库。

AS搭建JNI环境(方法一)

在SDK 管理器安装NDK和CMake
注:如果选择23.x及以上版本的ndk,toolchains目录下就缺失了aarch64-linux-android-4.9 这个目录,导致工程编译失败报错。所以安装23以下的版本:22.1.7171670

 在app的build.gradle中指定ndk版本号(这一步我直接省略了,因为我原来就有app的开发环境,sdk那些东西我早就配置好了,所以我可以直接用Android Studio来帮我编译。所以下面我介绍两种编译方法):

app项目文件

 创建一个空的项目

 

 

 添加一个目录,再添加两个文件

hellojni.c

#include <stdio.h>
#include <jni.h>
JNIEXPORT jstring JNICALL Java_com_lixiang_jniapptest_MainActivity_helloJNI(JNIEnv *env, jobject thiz){
        char* str = "hello from c!!";
        int a = 2/0;   //这两行是用来创建native_crash的
        str += a;
        return (*env)->NewStringUTF(env,str);
}

CMakeLists.txt

# 设置构建native library所需的CMake最低版本。
cmake_minimum_required(VERSION 3.4.1)

#创建一个库(多次调用add_library即可创建多个库)
add_library( # 设置库的名称
             hellojni
             # 将库设置为共享库(即so文件)
             SHARED
             # 指定源文件的相对路径
             hellojni.c )

在app的build.gradle中

android {
    ...

    defaultConfig {
        applicationId "com.lixiang.jniapptest"
        minSdk 21
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    ...
}

MainActivity.java(需要做一些修改)

package com.lixiang.jniapptest;

import android.os.Bundle;

import com.google.android.material.snackbar.Snackbar;

import androidx.appcompat.app.AppCompatActivity;

import android.view.View;

import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;

import com.lixiang.jniapptest.databinding.ActivityMainBinding;

import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private AppBarConfiguration appBarConfiguration;
    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        setSupportActionBar(binding.toolbar);

        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
        appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
        NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);

        binding.fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        System.loadLibrary("hellojni");
        Toast.makeText(getApplicationContext(), helloJNI(), Toast.LENGTH_SHORT).show();
    }

    public void hello(View view){
        //加载c代码生成的.so文件,so库的名称在描述文件中配置
        System.loadLibrary("hellojni");
        //调用处
        //ToastUtils.showMessage(helloJNI());
    }

    public native String helloJNI();

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
        return NavigationUI.navigateUp(navController, appBarConfiguration)
                || super.onSupportNavigateUp();
    }
}

编译方法一(适合没有配置过app开发环境的)

配置path环境变量

1)打开File > Project Structure > SDK Location,选择默认NDK的路径并复制。

 如果此处点击apply提示“NDK does not contain any platforms”表示版本过高,需下载更低版本的NDK。
2)右击我的电脑>属性>高级系统设置>环境变量>新建,添加一个系统变量NDK_HOME,并把刚才复制的ndk-bundle的路径填上去

 3)给Path系统变量(不需要创建),新建一个%NDK_HOME%

 验证是否配置成功

在Terminal/cmd中直接输入 ndk-build,出现如下内容配置成功。未出现请重启电脑(踩坑2)

 其他:如还未配置成功请看是否配置以下两处:

  编译方法二(配置过app开发环境)

Build->Build Bundle(s)/APK(s)->Build APK(s)生成一个apk文件

 生成的apk文件点击locate会打开那个文件夹(我的文件生成路径在AndroidStudioProjects/app/build/outputs/apk/debug)

AS搭建JNI环境(方法二)

因为我是有app开发环境的,所以我可以直接生成JNI环境,没有下载过nkd、sdk那些估计不可以

 

 选择Native C++,剩下就是填一下项目名,然后一直Next->Finish。

我的Setting设置如下:

 

 

 

标签:NDK,App,public,Android,import,JNI,app,android
From: https://www.cnblogs.com/kongbursi-2292702937/p/17217622.html

相关文章

  • android 10虚拟相机
    虚拟相机有很多用途,比如可以实现Android手机直播,刷脸等场景,最近无意间发现有人实现了这个功能,nvsh.xyz,根据官网https://nvsh.xyz视频可以实现用一个视频来替换摄像头,......
  • Android Studio学习笔记1
    Toast浮窗提示默认是底部弹出Menu隐藏菜单,不占据内存(表现为右上角的三个点)Intent进行启动活动(页面跳转),具有显示跳转和隐式跳转两个方式也可以传递信息控件——......
  • 京东App秒级百G日志传输存储架构设计与实战
    本文作者:平台业务研发部-武伟峰,数据与智能部-李阳背景在日常工作中,我们通常需要存储一些日志,譬如用户请求的出入参、系统运行时打印的一些info、error之类的日志,从而对系......
  • C - Make Takahashi Happy
    题目大意:左上角走到右下角,经过的路径权值连起来不能有重复,把没有重复的路径的条数加起来输出。我自己写的时候也磕磕绊绊,主要是自己模拟一边,理明白了就好了#include<ios......
  • Dapper 引入到项目
    Install-PackageDapperInstall-PackageMicrosoft.Extensions.ConfigurationInstall-PackageMicrosoft.Extensions.DependencyInjection.Abstractions通过NuGet,在......
  • 最新HCL AppScan Standard 10.1.028223 安装及 许可证注册
    最新HCLAppScanStandard10.1.028223安装及许可证注册参考原文:《最新HCLAppScanStandard10.1.028223》1、软件介绍1.1、旧版界面1.2、新版本界面1.3:介绍HCLAppS......
  • uniapp 蒲公英升级
    exportfunctioncheckUpdateApp(){//获取manifest.json里的配置信息plus.runtime.getProperty(plus.runtime.appid,function(widgetinfo){//可......
  • 搭建android源代码gitlab仓库
    git设置#gitconfig--globalhttp.postBuffer1048576000manifest.xml原始的manifests.xml文件在源头代码repo仓库中#ls-l.repo/total40drwxrwxr-x5100110......
  • Android.bp
    介绍Android.bp的出现就是为了替换Android.mk文件。bp跟mk文件不同,它是纯粹的配置,没有分支、循环等流程控制,不能做算数逻辑运算。如果需要控制逻辑,那么只能通过Go语言编......
  • uni-app+php:微信小程序登录:用code得到openid/unionid(hbuilderx 3.7.3)
    一,js代码:<template><view><buttonclass="login-wxpng"open-type="getUserInfo"@getuserinfo="xcxWxLogin">微信小程序登录......