Android逆向之旅-Android Studio的调用So文件极简教程(2022最新版Android Studio2021.3.1,踩坑版)

一、配置so需要的库环境

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

二、创建so文件的工程

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

在这里插入图片描述

下一步这些配置,自己按照喜好就好了
在这里插入图片描述

配置好该页面后,直接点击右下角的“Finish”,项目就算建好了。
记得需要用Project查看才是这样的。
在这里插入图片描述
在开发过程中,安卓想要调用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
这么长的函数名代表了一个个文件夹的关系
在这里插入图片描述
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文件,如图所示:
在这里插入图片描述
然后根据结构找到绿色框起来的文件这些就是编译生成的so文件
在这里插入图片描述

四、so文件存放

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

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

在这里插入图片描述

1)使用jniLibs文件夹

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

如图所示:

在这里插入图片描述

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

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

在这里插入图片描述

  • 注意!!!更改build.gradle文件需要Synv Now进行配置,不然无法运行!
    在这里插入图片描述

五、使用so文件

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

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

  • 在com.example包下面创建一个与so函数中层级一样的文件夹helloworld并且把MainActivity创建写好
    在这里插入图片描述
    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再进来就绿了。

在这里插入图片描述

  • 接下来就直接运行程序到手机上即可完成so文件的调用,中间的文字就是我们在编译so项目时候的native-lib文件出现的内容
    如图所示:
    在这里插入图片描述

在这里插入图片描述

六、结论

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

七、引用

https://zhuanlan.zhihu.com/p/477389360

猜你喜欢

转载自blog.csdn.net/qq_41866988/article/details/127604501
今日推荐