Android 尝试加载System.loadLibrary(“loader jni”)时应用程序崩溃

Android 尝试加载System.loadLibrary(“loader jni”)时应用程序崩溃,android,kotlin,java-native-interface,Android,Kotlin,Java Native Interface,编辑 fun getCompressVideo (video: String) { launch (Dispatchers.Main){ viewModel.mediaViewModel.video = videoCompressor.getCompressedVideo(context, Uri.parse(viewModel.mediaViewModel.video)) } } override suspend fun ge

编辑

fun getCompressVideo (video: String) {

        launch (Dispatchers.Main){
            viewModel.mediaViewModel.video = videoCompressor.getCompressedVideo(context, Uri.parse(viewModel.mediaViewModel.video))
        }
    }

override suspend fun getCompressedVideo(context: Context?, video: Uri): String {

            val retValue = withContext(Dispatchers.IO) {

                val inputFile = video.path
                Log.i("AMIRA3000" , inputFile)
                val loadJNI = LoadJNI()

                val workFolder: String = context!!.filesDir.absolutePath

                val outputFile: String = getFileFullName(
                    FilesConstants.VIDEO_FOLDER,
                    String.format(FilesConstants.VIDEO_NAME_FILE_FORMAT, System.currentTimeMillis())
                )

                val complexCommand = arrayOf(
                    "ffmpeg", "-y", "-i", inputFile, "-strict", "experimental", "-s", "320x240", "-r", "25", "-aspect", "4:3", "-ab", "48000", "-ac", "2", "-vcodec", "mpeg4", "-movflags", "+faststart", "-ar", "22050", "-b", "2097k", outputFile
                )

                loadJNI.run(complexCommand, workFolder, context)
            }

            return retValue.toString()
    }
公共最终类LoadJNI{
静止的{
加载库(“加载程序jni”);
}
/**
* 
*@param args ffmpeg命令
*@param workFolder工作目录
*@param ctx安卓上下文
*@param isValidate对命令应用验证
*@CommandValidationException
*/
public void run(String[]args,String workFolder,Context ctx,boolean isValidate)抛出CommandValidationException{
Log.i(Prefs.TAG,“运行ffmpeg4android_库:”+Prefs.version);
//删除以前的日志:这对于正确的进度计算至关重要
字符串vkLogPath=workFolder+“vk.log”;
deleteFileUtil(vkLogPath);
GeneralUtils.printCommand(args);
//打印结构(ctx);
如果(isValidate){
if(GeneralUtils.isValidCommand(args))
加载(args,workFolder,getVideokitLibPath(ctx),true);
其他的
抛出新的CommandValidationException();
}
否则{
加载(args,workFolder,getVideokitLibPath(ctx),true);
}
}
/**
* 
*@param args ffmpeg命令
*@param videokitSdcardPath工作目录
*@param ctx安卓上下文
*@CommandValidationException
*/
公共无效运行(字符串[]参数、字符串workFolder、上下文ctx)引发CommandValidationException{
运行(args,workFolder,ctx,true);
}
私有静态void printInternalDirStructure(上下文ctx){
Log.d(Prefs.TAG,“=printInternalDirStructure=”);
Log.d(Prefs.TAG,“====================================================”;
File File=新文件(ctx.getFilesDir().getParent());
analyzeDir(文件);
Log.d(Prefs.TAG,“====================================================”;
}
专用静态void analyzeDir(文件路径){
if(path.isDirectory()){
Log.d(Prefs.TAG,“扫描目录:+path.getAbsolutePath());
File[]files1=path.listFiles();
for(int i=0;i
该文件在库中找到


我知道现在回答这个问题已经晚了,但可能会帮助正在寻找答案的人。 我也遇到了同样的错误,我花了几天的时间来解决这个问题。 我已经尝试了所有可能的答案,但仍然无法解决它们。我使用的是一个旧项目,其中
jniLibs
已经存在,但仍然得到相同的错误。经过大量的研究,我得到了答案,它起了作用。这是我遵循的链接:

我只需要做三件事:

将此行添加到你的应用程序gradle.build:

实现'com.netcompss:ffmpeg4android_lib:41.08'

将此添加到gradle.properties:

android.usedpreprecatedndk=true

将其添加到清单文件中的应用程序标记中:

android:extractNativeLibs=“true”


我希望它能帮助某些人:祝你好运。

崩溃发生在你的LoadJNI()方法中,你还没有发布这个方法。这没什么关系
fun getCompressVideo (video: String) {

        launch (Dispatchers.Main){
            viewModel.mediaViewModel.video = videoCompressor.getCompressedVideo(context, Uri.parse(viewModel.mediaViewModel.video))
        }
    }

override suspend fun getCompressedVideo(context: Context?, video: Uri): String {

            val retValue = withContext(Dispatchers.IO) {

                val inputFile = video.path
                Log.i("AMIRA3000" , inputFile)
                val loadJNI = LoadJNI()

                val workFolder: String = context!!.filesDir.absolutePath

                val outputFile: String = getFileFullName(
                    FilesConstants.VIDEO_FOLDER,
                    String.format(FilesConstants.VIDEO_NAME_FILE_FORMAT, System.currentTimeMillis())
                )

                val complexCommand = arrayOf(
                    "ffmpeg", "-y", "-i", inputFile, "-strict", "experimental", "-s", "320x240", "-r", "25", "-aspect", "4:3", "-ab", "48000", "-ac", "2", "-vcodec", "mpeg4", "-movflags", "+faststart", "-ar", "22050", "-b", "2097k", outputFile
                )

                loadJNI.run(complexCommand, workFolder, context)
            }

            return retValue.toString()
    }
public final class LoadJNI {

    static {
        System.loadLibrary("loader-jni");
    }

    /**
     * 
     * @param args ffmpeg command
     * @param workFolder working directory 
     * @param ctx Android context
     * @param isValidate apply validation to the command
     * @throws CommandValidationException
     */
    public void run(String[] args, String workFolder, Context ctx, boolean isValidate) throws CommandValidationException {
        Log.i(Prefs.TAG, "running ffmpeg4android_lib: " + Prefs.version);
        // delete previous log: this is essential for correct progress calculation
        String vkLogPath = workFolder + "vk.log";
        GeneralUtils.deleteFileUtil(vkLogPath);
        GeneralUtils.printCommand(args);

        //printInternalDirStructure(ctx);

        if (isValidate) {
            if (GeneralUtils.isValidCommand(args))
                load(args, workFolder, getVideokitLibPath(ctx), true);
            else
                throw new CommandValidationException();
        }
        else {
            load(args, workFolder, getVideokitLibPath(ctx), true);
        }

    }

    /**
     * 
     * @param args ffmpeg command
     * @param videokitSdcardPath working directory 
     * @param ctx Android context
     * @throws CommandValidationException
     */
    public void run(String[] args, String workFolder, Context ctx) throws CommandValidationException {
        run(args, workFolder, ctx, true);
    }


    private static void printInternalDirStructure(Context ctx) {
        Log.d(Prefs.TAG, "=printInternalDirStructure=");
        Log.d(Prefs.TAG, "==============================");
        File file = new File(ctx.getFilesDir().getParent());
        analyzeDir(file);
        Log.d(Prefs.TAG, "==============================");
    }

    private static void analyzeDir(File path) {
        if (path.isDirectory()) {
            Log.d(Prefs.TAG,"Scanning dir: " + path.getAbsolutePath());
            File[] files1 = path.listFiles();
            for (int i = 0; i < files1.length; i++) {
                analyzeDir(files1[i]);
            }
            Log.d(Prefs.TAG, "==========");
        }
        else {
            Log.d(Prefs.TAG, path.getAbsolutePath());

        }
    }

    private static String getVideokitLibPath(Context ctx) {

        //File file = new File(ctx.getFilesDir().getParent() + "/lib/");
        //analyzeDir(file);

        String videokitLibPath = ctx.getFilesDir().getParent()  + "/lib/libvideokit.so";

        File file = new File(videokitLibPath);
        if(file.exists())  {     
          Log.i(Prefs.TAG, "videokitLibPath exits: " + videokitLibPath);
        }
        else {
            Log.w(Prefs.TAG, "videokitLibPath not exits: " + videokitLibPath);
            videokitLibPath = ctx.getFilesDir().getParent()  + "/lib/arm64/libvideokit.so";
            Log.i(Prefs.TAG, "trying videokitLibPath: " + videokitLibPath);
            file = new File(videokitLibPath);
            if(file.exists())  {
                Log.i(Prefs.TAG, "videokitLibPath exits: " + videokitLibPath);
            }
            else {
                Log.w(Prefs.TAG, "videokitLibPath not exits: " + videokitLibPath);
                videokitLibPath = "/data/app/com.examples.ffmpeg4android_demo-1/lib/arm64/libvideokit.so";
                Log.i(Prefs.TAG, "trying videokitLibPath: " + videokitLibPath);
                file = new File(videokitLibPath);
                if(file.exists())  {
                    Log.i(Prefs.TAG, "videokitLibPath exits: " + videokitLibPath);
                }
                else {
                    Log.w(Prefs.TAG, "videokitLibPath not exits: " + videokitLibPath);
                    videokitLibPath = "/data/app/com.examples.ffmpeg4android_demo-2/lib/arm64/libvideokit.so";
                    Log.i(Prefs.TAG, "trying videokitLibPath: " + videokitLibPath);
                    if(file.exists())  {
                        Log.i(Prefs.TAG, "videokitLibPath exits: " + videokitLibPath);
                    }
                    else {
                        Log.e(Prefs.TAG, "can't find path of lib");
                    }
                }
            }
        }





        //String videokitLibPath = ctx.getFilesDir().getParent()  + "/lib/arm64/libvideokit.so";

        // only this works on Android M, and the number changes (demo-2, demo-1)
        //String videokitLibPath = "/data/app/com.examples.ffmpeg4android_demo-1/lib/arm64/libvideokit.so";


        Log.i(Prefs.TAG, "videokitLibPath: " + videokitLibPath);
        return videokitLibPath;

    }



    public void fExit( Context ctx) {
        fexit(getVideokitLibPath(ctx));
    }

    public native String fexit(String videokitLibPath);

    public native String unload();

    public native String load(String[] args, String videokitSdcardPath, String videokitLibPath, boolean isComplex);
}