AndroidStudio封装.so傻瓜教程

. Android Studio --- 生成.so

step.1 新建空项目My Application 

step.2 在local.properties添加ndk路径,并选择jdk版本

 

step.3 在 app\src\main 下创建文件夹jni

   在jni下放入.c代码以及创建Android.mk 和 Application.mk文件,具体配置如下

如果是.cpp文件,Android.mk配置以下参考:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# 添加你的头文件目录
# LOCAL_C_INCLUDES += $(LOCAL_PATH)/include

# 添加依赖库
LOCAL_LDLIBS := -lc++

# 生成.so的名称
LOCAL_MODULE := encode
# 用于封装的源文件
LOCAL_SRC_FILES := encode.cpp

include $(BUILD_SHARED_LIBRARY)

Application.mk配置如下参考:

step.4 把用于封装的源文件中的接口函数按jni格式修改

添加头文件

#include <jni.h>

 上述为实现打印hello from C的接口函数代码示例,

Java_com_example_myapplication_MainActivity_helloC

Java _ 包名 _ 类名 _ 接口函数() 

上述为实现encode的代码

 ***当封装的是Cpp文件时,接口函数需要加上extern "C"***

 JNI格式ps:fopen函数中第一个路径参数必须为const char*,需要用

(*env)->GetStringUTFChars(env, originalfilePath, NULL)

或者

env->GetStringUTFChars(infilepath, NULL)

来将java string字符串转换为const char *,输出字符串同理,需要将字符串转化为java string

(*(*env)).NewStringUTF(env, "file open failed2")
env->NewStringUTF("outputFile open failed")

step.5 进行ndk-build  cmd到jni目录下,运行ndk-build,会在main目录下生成libs文件夹,即生成的.so文件

 二. Android Studio --- 调用.so

step.1 在build.gradle (:app) 中添加so库源路径

sourceSets {
        main{
            jniLibs.srcDirs   'src/main/libs'
        }
    }

step.2 在 java 下编写 java 文件进行调用

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.example.myapplication.R;

public class MainActivity extends AppCompatActivity {

    //*********1.加载 so 库**********
    static{
        System.loadLibrary("encode"); //写入so库名称
                                      //如果是编译的是cpp文件的话,可能需要链接一些C++中so库
      //System.loadLibrary("c++_shared");  链接的库也需要放入libs文件夹下
                                      //参考路径 D:\SDK\ndk-bundle\sources\cxx-stl\llvm-libc++\libs
    }

    private TextView textView;

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

        textView = findViewById(R.id.textView);
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 调用 C++ 函数并显示返回的字符串
                String originalfilePath = "/storage/emulated/0/DCIM/1.bmp";
                String outputfilePath="/storage/emulated/0/DCIM/output.bmp";
                String plainfilePath = "asdxcnvvhdje";
                String result = projectJNI(originalfilePath,outputfilePath,plainfilePath);
                textView.setText(result);
            }
        });
    }

上述为java调用libencode.so内的projectJNI()方法,实现encode过程,若成功返回字符串“success”给result,得到的结果如下图所示:

PS. 为了访问虚拟机内的文件,需要设置两个tip

tips1. 在 AndroidManifest.xml 中添加代码

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

tips2. 在虚拟机中设置安装app的Permission

 

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值