Android Studio 编译c++文件生成so文件,调用并打jar包使用

  • 第1步:新建一个Android Studio 工程 gmos。新建一个GmosJni.java文件。在这里插入图片描述
    在这里插入图片描述
  • 第2步:点击一下 make project 会在app的build目录下面生成.class文件。
    在这里插入图片描述
  • 第3步,在app/src/main文件夹下新建一个jni文件夹,然后打开Android Studio的Terminal终端,cd到这个目录,然后输入下面的指令
javah -jni -classpath F:\MyWorkSpace\android_worksapce\mosToSo\gmos\app\build\intermediates\javac\debug\compileDebugJavaWithJavac\classes mlab.android.gmos.GmosJni

  • 就会在这个jni文件夹下生成一个.h文件,mlab_android_gmos_GmosJni.h,文件内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class mlab_android_gmos_GmosJni */

#ifndef _Included_mlab_android_gmos_GmosJni
#define _Included_mlab_android_gmos_GmosJni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     mlab_android_gmos_GmosJni
 * Method:    calMOSc
 * Signature: ([Lmlab/android/gmos/pojo/CloudGameInfo;I)[D
 */
JNIEXPORT jdoubleArray JNICALL Java_mlab_android_gmos_GmosJni_calMOSc
  (JNIEnv *, jclass, jobjectArray, jint);

#ifdef __cplusplus
}
#endif
#endif

  • 第4步:在jni目录下新建一个c/c++source file ,取名mlab_android_gmos_GmosJni.cpp 实现上面.h文件中的方法。
//
// Created by Administrator on 2019/11/22.
//
#include "gMOS.h"
#include "mlab_android_gmos_GmosJni.h"

JNIEXPORT jdoubleArray JNICALL Java_mlab_android_gmos_GmosJni_calMOSc
        (JNIEnv *env, jclass jz, jobjectArray cloudGameFullInfo , jint InfoArrLen){
    int size = env->GetArrayLength(cloudGameFullInfo);
    CloudGameInfo cloudGameInfo[size];
    int i = 0;
    for (i = 0; i < size; i++) {

        jobject obj_cloudGameFullInfo = (jobject) env->GetObjectArrayElement(cloudGameFullInfo, i);
        jclass cls_cloudGameInfo = env->GetObjectClass(obj_cloudGameFullInfo);

        //video_codec
        jfieldID video_codecFieldID = env->GetFieldID(cls_cloudGameInfo, "video_codec", "I");
        jint video_codec = env->GetIntField(obj_cloudGameFullInfo, video_codecFieldID);

        //video_bitrate
        jfieldID video_bitrateFieldID = env->GetFieldID(cls_cloudGameInfo, "video_bitrate", "D");
        jdouble video_bitrate = env->GetDoubleField(obj_cloudGameFullInfo, video_bitrateFieldID);

        //video_framerate
        jfieldID video_framerateFieldID = env->GetFieldID(cls_cloudGameInfo, "video_framerate", "D");
        jdouble video_framerate = env->GetDoubleField(obj_cloudGameFullInfo, video_framerateFieldID);

        //video_horizontal_resolution
        jfieldID video_horizontal_resolutionFieldID = env->GetFieldID(cls_cloudGameInfo, "video_horizontal_resolution", "D");
        jdouble video_horizontal_resolution = env->GetDoubleField(obj_cloudGameFullInfo, video_horizontal_resolutionFieldID);

        //video_vertical_resolution
        jfieldID video_vertical_resolutionFieldID = env->GetFieldID(cls_cloudGameInfo, "video_vertical_resolution", "D");
        jdouble video_vertical_resolution = env->GetDoubleField(obj_cloudGameFullInfo, video_vertical_resolutionFieldID);

        //ppd
        jfieldID ppdFieldID = env->GetFieldID(cls_cloudGameInfo, "ppd", "D");
        jdouble ppd = env->GetDoubleField(obj_cloudGameFullInfo, ppdFieldID);

        //device_framerate
        jfieldID device_framerateFieldID = env->GetFieldID(cls_cloudGameInfo, "device_framerate", "D");
        jdouble device_framerate = env->GetDoubleField(obj_cloudGameFullInfo, device_framerateFieldID);

        //audio_bitrate
        jfieldID audio_bitrateFieldID = env->GetFieldID(cls_cloudGameInfo, "audio_bitrate", "D");
        jdouble audio_bitrate = env->GetDoubleField(obj_cloudGameFullInfo, audio_bitrateFieldID);

        //audio_video_asyn_delay
        jfieldID audio_video_asyn_delayFieldID = env->GetFieldID(cls_cloudGameInfo, "audio_video_asyn_delay", "D");
        jdouble audio_video_asyn_delay = env->GetDoubleField(obj_cloudGameFullInfo, audio_video_asyn_delayFieldID);

        //operration_response_delay_average
        jfieldID operration_response_delay_averageFieldID = env->GetFieldID(cls_cloudGameInfo, "operration_response_delay_average", "D");
        jdouble operration_response_delay_average = env->GetDoubleField(obj_cloudGameFullInfo, operration_response_delay_averageFieldID);

        //audio_video_asyn_delay
        jfieldID packet_loss_rate_averageFieldID = env->GetFieldID(cls_cloudGameInfo, "packet_loss_rate_average", "D");
        jdouble packet_loss_rate_average = env->GetDoubleField(obj_cloudGameFullInfo, packet_loss_rate_averageFieldID);

        CloudGameInfo info;
        info.video_codec = video_codec;
        info.video_bitrate = video_bitrate;
        info.video_framerate = video_framerate;
        info.video_horizontal_resolution = video_horizontal_resolution;
        info.video_vertical_resolution = video_vertical_resolution;
        info.ppd = ppd;
        info.device_framerate = device_framerate;
        info.audio_bitrate = audio_bitrate;
        info.audio_video_asyn_delay = audio_video_asyn_delay;
        info.operration_response_delay_average = operration_response_delay_average;
        info.packet_loss_rate_average = packet_loss_rate_average;

        cloudGameInfo[i] = info;
    }

    GMOS gmos = calMOSc(cloudGameInfo,InfoArrLen);

    jdouble value_array[5];
    value_array[0] = gmos.MOSv;;
    value_array[1] = gmos.MOSav;
    value_array[2] = gmos.MOSi;
    value_array[3] = gmos.MOSp;
    value_array[4] = gmos.MOSc;

    jdoubleArray ret;
    ret = env->NewDoubleArray(5);
    env->SetDoubleArrayRegion(ret, 0, 5, value_array);

    return ret;
}

  • 第5步:在jni文件夹下新建Android.mk和Application.mk文件
    在这里插入图片描述
  • Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := _gmos
LOCAL_SRC_FILES := mlab_android_gmos_GmosJni.cpp\
                   gMOS.cpp
include $(BUILD_SHARED_LIBRARY)
  • Application.mk
APP_ABI := all
  • 第6步,关联下载好的ndk包
    在这里插入图片描述
  • 第7步:在终端Terminal进入到jni目录,输入指令 ndk-build,就会生成相应的so文件。
    在这里插入图片描述
  • 第8步:调用so文件。
    在app的bulid文件中加入如下代码,然后build project
android {
    ...
    sourceSets {
        main() {
            jniLibs.srcDirs = ['src/main/libs']
            jni.srcDirs = [] //屏蔽掉默认的jni编译生成过程
        }
    }
}
  • 第9步:在MainActivity中调用
package mlab.android.gmos;

import androidx.appcompat.app.AppCompatActivity;

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

import mlab.android.gmos.pojo.CloudGameInfo;

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.sample_text);
        CloudGameInfo[] cloudGameInfos = {new CloudGameInfo()};
        double[] re = GmosJni.calMOSc(cloudGameInfos,1);
        String rr = "";
        for (int i = 0; i < re.length; i++) {
            rr += re[i] + "***";
        }
        textView.setText(rr);
    }
}

  • activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/sample_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
  • 运行结果
    在这里插入图片描述

接下来是打jar包使用so文件

  • 第1步:删除一些无用的资源,如MainActivity,layout等,只留下和JNI有关的java类
    在这里插入图片描述
  • 第2步:修改module的build.gradle文件
  • 修改一:将最前面的apply plugin: 'com.android.application’修改为apply plugin: ‘com.android.library’
  • 修改二:将defaultConfig修改为(版本根据需要修改):
defaultConfig {
        minSdkVersion 16
        targetSdkVersion 29
    }
  • 修改三:
android {
...
 task deleteOldJar(type: Delete) {
        delete 'build/outputs/test.jar'
    }

    task exportJar(type: Copy) {
        from('build/intermediates/packaged-classes/release/')
        into('build/libs/')
        include('classes.jar')
        rename ('classes.jar', 'gmos.jar')
    }

    exportJar.dependsOn(deleteOldJar, build)
}
  • 第3步:导出jar包,打开Gradle,打开app->Tasks->other->exportJar 双击exportJar
    在这里插入图片描述
    在这里插入图片描述

使用jar包

  • 第1步:将so文件与jar包放入项目libs文件夹中
    在这里插入图片描述
  • 第:2步:在app的bulid文件中加入如下代码,然后build project
android {
    ...
    sourceSets {
        main() {
            jniLibs.srcDirs = ['libs']
            jni.srcDirs = [] //屏蔽掉默认的jni编译生成过程
        }
    }
}
  • 第3步:multiDexEnabled true 与 implementation ‘com.android.support:multidex:1.0.1’
    在这里插入图片描述
    在这里插入图片描述
  • 第4步:在在MainActivity中调用,显示结果
    在这里插入图片描述
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Timothy Cui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值