首页
社区
课程
招聘
[原创]安卓日记_新版本AndroidStudio编写so文件
2022-10-14 10:43 5670

[原创]安卓日记_新版本AndroidStudio编写so文件

2022-10-14 10:43
5670

新版本AndroidStudio编写so文件

建议先通读全文然后再操作.

新建JNI类


1
2
3
4
5
6
7
8
9
package com.example.day5_so;
 
public class ymtJNI {
    static {
        System.loadLibrary("JniFirst");
        //要加载so的文件名,这里暂时没有so
    }
    public static native String sayHi();
}

选中ymtJNI,右键在浏览器中进行打开

 

 

将目录进行复制

 

生成class文件

用javac将java文件编译成class文件

1
javac ymtJNI.java

 

生成.h文件

 

java10,java11及以上

1
javac -h .\ ymtJNI.java

发现生成成功

新建.c文件

将项目切换成project视图,并在main目录下新建一个jni的目录

 

直接Finish,不用换位置

 

新建完后会生成jni的一个目录,右键新建一个main.c文件

 

 

 

然后将上面生成的.h文件中的内容复制进去

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_day5_so_ymtJNI */
 
#ifndef _Included_com_example_day5_so_ymtJNI
#define _Included_com_example_day5_so_ymtJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_day5_so_ymtJNI
 * Method:    sayHi
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_day5_1so_ymtJNI_sayHi
  (JNIEnv *, jclass);
 
#ifdef __cplusplus
}
#endif
#endif

然后将sayHi函数给完善起来,完善后(后面发现这样其实完善的有语法错误的)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_day5_so_ymtJNI */
 
#ifndef _Included_com_example_day5_so_ymtJNI
#define _Included_com_example_day5_so_ymtJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_day5_so_ymtJNI
 * Method:    sayHi
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_day5_1so_ymtJNI_sayHi
  (JNIEnv *env, jclass jobj);
//返回一句"Hi"
    return (*env)->NewStrinUTF(env,"Hi!");
#ifdef __cplusplus
}
#endif
#endif

配置NDK

首先下载:

 

NDK 下载 | Android NDK | Android Developers (google.cn)

 

打开local.properties,添加ndk的目录

 

 

打开app模块下的build.gradle

 

 

添加ndk的配置信息,其中moduleName为要调用so的名字

1
2
3
4
5
ndk {
    moduleName "JniFirst"
    ldLibs "log", "z", "m"
    abiFilters "arm64-v8a", "armeabi-v7a", "x86_64","x86"
}

 

再打开gradle.properties,添加

1
android.useDeprecatedNdk=true

 

然后我们将项目进行build

 

 

就可以生成so文件了

 

发现报错

1
2
3
4
The option 'android.useDeprecatedNdk' is deprecated.
The current default is 'false'.
It has been removed from the current version of the Android Gradle plugin.
NdkCompile is no longer supported

 

可恶,生成失败,这个方式已经被弃用了。

cmake生成so库

安装cmake

 

 

 

安装后最好重启下。

 

重新安装上面的步骤重新再来次.

重新来次

新建MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.example.day5_so2;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
 
public class MainActivity extends AppCompatActivity {
 
    TextView TV_content;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TV_content=findViewById(R.id.TV_content);
        //TV_content.setText(ymtJNI.sayHi());
        //Log.d("onCreate: ",ymtJNI.sayHi());
    }
}

新建ymtJNI.java

1
2
3
4
5
6
7
8
9
package com.example.day5_so2;
 
public class ymtJNI {
    static {
        System.loadLibrary("JniFirst");
        //要加载so的文件名,这里暂时没有so
    }
    public static native String sayHi();
}

用javac将ymtJNI.java生成ymtJNI.class文件

1
javac ymtJNI.java

用javac将ymtJNI.java生成.h文件

1
javac -h .\ ymtJNI.java

 

然后新建jni目录,在jni目录中新建main.c文件

 

我们可以同时将.h文件复制一份放到同一目录然后include引入,当然也可以直接将里面的内容复制进来直接进行修改(上面的是不正确的)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_day5_so2_ymtJNI */
 
#ifndef _Included_com_example_day5_so2_ymtJNI
#define _Included_com_example_day5_so2_ymtJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_day5_so2_ymtJNI
 * Method:    sayHi
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_day5_1so2_ymtJNI_sayHi
  (JNIEnv *env, jclass jobj)                            //注意这里的";"去掉
{                                                       //要加上"{"
    //返回一句"Hi"
    return (*env)->NewStringUTF(env,"Hi!");            //NewStringUTF不要写错
    //return env->NewStringUTF((char *)"Hi");
}
#ifdef __cplusplus
}
#endif
#endif

配置CMakeLists.txt

然后我们需要在src的同目录下新建CMakeLists.txt

 

内容复制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
cmake_minimum_required(VERSION 3.4.1)
 
add_library( # Sets the name of the library.
# 设置so文件名称.
JniFirst
# Sets the library as a shared library.
SHARED
# 设置这个so文件为共享.
# Provides a relative path to your source file(s).
# 设置这个so文件为共享.
src/main/jni/main.c)
 
 
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
 
target_link_libraries( # Specifies the target library.
# 制定目标库.
JniFirst
# Links the target library to the log library
# included in the NDK.
${log-lib} )

记得修改箭头所指向的内容.

 

 

在build.gradle里面配置Cmake工具和配置CmakeLists.txt路径(注意看红框框的位置)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
plugins {
    id 'com.android.application'
}
 
android {
    compileSdk 32
 
    defaultConfig {
        applicationId "com.example.day5_so2"
        minSdk 16
        targetSdk 32
        versionCode 1
        versionName "1.0"
 
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        //配置Cmake工具
        externalNativeBuild{
            cmake{
                cppFlags ""
                abiFilters "arm64-v8a","armeabi-v7a",'x86','x86_64'
            }
        }
    }
    //配置CmakeLists.txt路径
    externalNativeBuild{
        cmake{
            path "CMakeLists.txt"
        }
    }
 
 
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}
 
dependencies {
 
    //noinspection GradleCompatible
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:2.0.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

哦哦,对了,要需要配置NDK

 

生成so文件

然后build即可,发现成功有看到so文件

 

同时apk也成功运行

 


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2022-10-14 10:52 被陌上恋静编辑 ,原因: 二级标题没有显示出来
收藏
点赞1
打赏
分享
最新回复 (1)
雪    币: 309
活跃值: (960)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
陌上恋静 2022-10-14 10:47
2
0
本人菜鸡一枚,欢迎大佬们陆续加入到QQ群 801022487 一起交流学习.
游客
登录 | 注册 方可回帖
返回