一、配置so需要的库环境

高版本的Android Studio已经集成了LLDB调试库,所以说,大家不要在找为什么没有,该从哪里去找。现在很多教程都是老的,这个算是我用的这个版本的最新方法,踩坑版。

File->setting

Android 配置公共so库 android调用so库_so文件

二、创建so文件的工程

直接选择最后一个
File->New project

Android 配置公共so库 android调用so库_android studio_02

下一步这些配置,自己按照喜好就好了

Android 配置公共so库 android调用so库_Android 配置公共so库_03

配置好该页面后,直接点击右下角的“Finish”,项目就算建好了。

记得需要用Project查看才是这样的。

Android 配置公共so库 android调用so库_so文件_04


在开发过程中,安卓想要调用C++代码是不能直接调用的,这时,就需要一个中间键来通信,在上述图片汇总,“native-lib.cpp”这就是两个不同平台的中间键代码,编译的最终so文件也是调用的"native-lib.cpp"中的函数内容。

native-lib文件内容如下:

#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());
}

函数名: Java_com_example_helloworld_MainActivity_stringFromJNI

这么长的函数名代表了一个个文件夹的关系

Android 配置公共so库 android调用so库_so文件_05


MainActivity文件内容如下:

package com.example.helloworld;

import androidx.appcompat.app.AppCompatActivity;

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

import com.example.helloworld.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    // Used to load the 'helloworld' library on application startup.
    static {
        System.loadLibrary("helloworld");
    }

    private ActivityMainBinding binding;

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

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

        // Example of a call to a native method
        TextView tv = binding.sampleText;
        tv.setText(stringFromJNI());
    }

    /**
     * A native method that is implemented by the 'helloworld' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
}

想要哪个函数与C++通信,那么哪个函数前面就需要有"native"字样表示。在MainActivity最后的stringFromJNI函数是需要生成so文件被调用的。

三、 编译so文件

选中Make Project直接编译"Hello World"项目,编译完成之后会在app中出现一个build文件,如图所示:

Android 配置公共so库 android调用so库_so文件_06


然后根据结构找到绿色框起来的文件这些就是编译生成的so文件

Android 配置公共so库 android调用so库_ide_07

四、so文件存放

编译完成后,接下来是该如何使用编译好的so文件。
注意!!!
这部分内容是最新的,网上很多办法都已经过时或者起冲突了,导致现在一搜索使用so文件就千篇一律,毫无帮助。

选中"Empty Activity"类型创建项目,名称随意

Android 配置公共so库 android调用so库_android studio_08

1)使用jniLibs文件夹

  • 在app->src->main中创建一个叫做:jniLibs文件夹。
  • 把 cmake编译的so文件放入这里,就算配置完成了。
  • 没有看错,不用和网上大多数教程一样去修改app文件夹下的"build.gradle", 不需要!!!

如图所示:

Android 配置公共so库 android调用so库_ide_09

2)使用libs文件夹(不建议)

  • 用这个文件夹的好处就是不需要再去创建新的文件夹了,
  • 把 cmake编译的so文件放入app文件夹下的libs文件夹
  • 但是还需要额外的配置app文件夹下的"build.gradle"。
  • 在build.gradle文件里面添加上这一段代码,指定libs代替jniLibs的作用即可,不需要添加其他代码!!!
  • 此时,so文件所需的内容就已经配置完成了。
sourceSets {
    main{
        main.jni.srcDirs = []
        main.jniLibs.srcDirs = ['libs']
    }
}

Android 配置公共so库 android调用so库_ide_10

  • 注意!!!更改build.gradle文件需要Synv Now进行配置,不然无法运行!

五、使用so文件

  • 在中间键文件:native-lib.cpp中,有一个默认的函数,函数名是:Java_com_example_helloworld_MainActivity_stringFromJNI

  • 当我们在调用so的位置也需要按照so中函数名的方式创建一个一模一样的路径,并且类名叫做:MainActivity,有一个叫做stringFromJNI的函数,只有这样才会调用成功。

  • 在com.example包下面创建一个与so函数中层级一样的文件夹helloworld并且把MainActivity创建写好
  • Android 配置公共so库 android调用so库_android_11

  • MainActivity文件内容:
package com.example.helloworld;

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

import androidx.appcompat.app.AppCompatActivity;

import com.example.userandroidtest1.R;


public class MainActivity extends AppCompatActivity {

    // Used to load the 'helloworld' library on application startup.
    static {
        System.loadLibrary("helloworld");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView tv = findViewById(R.id.stong);
        /*R.id.stong中的stong是我自己在activity_main.xml命名的id,可以自己更改*/
        tv.setText(stringFromJNI());
    }
    /**
     * A native method that is implemented by the 'helloworld' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
}
  • 接下来就是调用了,可以看到有两个MainActivity,这是肯定无法调用的
    我们需要到main->AndroidManifest.xml文件下去更改调用关系来让程序运行的是我们调用so文件的那个MainActivity。
android:name="com.example.helloworld.MainActivity"
  • 这样就可以指定MainActivity了,如果红了不要慌,确定路径并且拼写正确,重新启动Android Stuio再进来就绿了。

Android 配置公共so库 android调用so库_android_12

  • 接下来就直接运行程序到手机上即可完成so文件的调用,中间的文字就是我们在编译so项目时候的native-lib文件出现的内容
    如图所示:
  • Android 配置公共so库 android调用so库_ide_13


Android 配置公共so库 android调用so库_Android 配置公共so库_14

六、结论

希望那些抄代码,抄文章的同志,抄下来麻烦自己运行一次,不要误导后人,就这么点任务量,让我看了网上无数教程,各种误导,最后才总结出来的。