【问题标题】:java.lang.NoClassDefFoundError Android Studio Unityjava.lang.NoClassDefFoundError Android Studio Unity
【发布时间】:2016-08-23 02:39:33
【问题描述】:

当我尝试在 Android Studio 中生成包含另一个库的库时遇到了一些麻烦。首先,我使用的是 Android Studio 2.0 和 Unity 5.3.4f1。我想做的是在 Unity 中集成 FFMpeg,所以我决定创建自己的库,使用 FFMpeg 库作为中介。 FFMpeg 库是here

首先我在 Android Studio 中创建了一个新的空项目,并在其中创建了一个新模块,这将是我的库,使用 New->Module->Android Library 并将其命名为“ ffmpeg编解码器”。之后,我在新模块文件夹中打开 build.gradle 文件并粘贴:

compile 'com.writingminds:FFmpegAndroid:0.3.2'

在依赖括号内,然后单击同步(它没有显示任何错误)。

之后在 src/main/java/package-name/ 中创建一个新的 Java 类并将其命名为 FFMpegCodec。在此粘贴此代码:

public class FFMpegCodec {
private static FFmpeg ffmpeg;
private static Context context;
private static FFMpegCodec INSTANCE = null;

public FFMpegCodec(){
    INSTANCE = this;
}

public static FFMpegCodec instance(){
    if(INSTANCE == null){
        INSTANCE = new FFMpegCodec();
    }
    return INSTANCE;
}

public void setContext(Context ctx){
    this.context = ctx;
}

public void loadFFMpegBinary() {
    try {
        if (ffmpeg == null) {

            ffmpeg = FFmpeg.getInstance(context);
        }
        ffmpeg.loadBinary(new LoadBinaryResponseHandler() {
            @Override
            public void onFailure() {
                Log.e("FFMPEG", "ffmpeg : NOT correct Loaded");
            }

            @Override
            public void onSuccess() {
                Log.e("FFMPEG", "ffmpeg : correct Loaded");
            }
        });
    } catch (FFmpegNotSupportedException e) {

    } catch (Exception e) {

    }
}

public void execFFmpegCommand(final String[] command) {
    try {
        ffmpeg.execute(command, new ExecuteBinaryResponseHandler() {
            @Override
            public void onFailure(String s) {
                Log.e("FFMPEG", "FAILED with output : " + s);
            }

            @Override
            public void onSuccess(String s) {
                Log.e("FFMPEG", "SUCCESS with output : " + s);
            }

            @Override
            public void onProgress(String s) {
                Log.e("FFMPEG", "Started command : ffmpeg " + command);
                Log.e("FFMPEG", "progress : " + s);
            }

            @Override
            public void onStart() {
                Log.e("FFMPEG", "Started command : ffmpeg " + command);

            }

            @Override
            public void onFinish() {
                Log.e("FFMPEG", "Finished command : ffmpeg " + command);

            }
        });
    } catch (FFmpegCommandAlreadyRunningException e) {
        // do nothing for now
    }
}

它基本上生成一个 FFmpeg 实例并调用 ffmpeg 命令。

一旦我完成了我的 lib,我决定在我的项目中对其进行测试,因此我将我的 lib 包含在我的应用程序 graddle 中:

compile project(':ffmpegcodec')

之后,我只需将此代码粘贴到我的 MainActivity:

public class MainActivity extends AppCompatActivity {

FFMpegCodec ffmpeg;

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

    Button execCommandButton = (Button) findViewById(R.id.execCommandButton);

    ffmpeg = FFMpegCodec.instance();


    execCommandButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(getApplicationContext(), "This is a Toast!!", Toast.LENGTH_SHORT).show();
            ffmpeg.setContext(MainActivity.this);
            ffmpeg.loadFFMpegBinary();
            String []cmd = new String[1];
            cmd[0] = "-version";
            ffmpeg.execFFmpegCommand(cmd);
        }
    });

}

之后,我运行我的项目,当我按下按钮时,它返回一切正常,显示 ffmpeg 版本。 一旦我检查了我的 lib 工作正常,我决定将其移动到 Unity,因此将 ffmpegcodec-realese.arr 文件复制到 ffmpegcodec/build/outputs/aar 文件夹中并粘贴它进入我的 Unity 项目。然后我编写了一个 C# 脚本来使用我的 lib,其中包含:

    using System;
    using System.Runtime.InteropServices;
    using UnityEngine;
    using System.Collections;
    using System.Diagnostics;

    public class ScreenRecorder {

    private AndroidJavaObject unityActivity = null;
    private AndroidJavaObject captureObject = null;

        // Use this for initialization
        public ScreenRecorder () {
            try{

                using (AndroidJavaClass unityPlayerActivityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) {
                    unityActivity = unityPlayerActivityClass.GetStatic<AndroidJavaObject>("currentActivity");
                }

                AndroidJavaClass captureClass = new AndroidJavaClass ("com.promineostudios.ffmpegcodec.FFMpegCodec");
                if (captureClass != null) {
                    captureObject = captureClass.CallStatic<AndroidJavaObject>("instance");
                    captureObject.Call("setContext", unityActivity);
                    captureObject.Call("loadFFMpegBinary");
                }
            }catch(Exception ex){
                UnityEngine.Debug.Log(ex);
            }
        }

    }

问题来了。当我使用以下方法创建类实例时:

AndroidJavaClass captureClass = new AndroidJavaClass ("com.promineostudios.ffmpegcodec.FFMpegCodec");

它正确地创建了一个实例,并且当我使用以下方法创建一个对象时:

captureObject = captureClass.CallStatic<AndroidJavaObject>("instance");

但是当我尝试访问“setContext”中的 FFMpeg 库方法时,它会失败并返回:

UnityEngine.AndroidJavaException: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/github/hiteshsondhi88/libffmpeg/FFmpeg;
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/github/hiteshsondhi88/libffmpeg/FFmpeg;
  at com.promineostudios.ffmpegcodec.FFMpegCodec.loadFFMpegBinary(FFMpegAndroidCodec.java:39)
  at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
  at com.unity3d.player.UnityPlayer.a(Unknown Source)
  at com.unity3d.player.UnityPlayer$b.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.github.hiteshsondhi88.libffmpeg.FFmpeg" on path: DexPathList[[zip file "/data/app/com.promineostudios.ffmpegmodule-1/base.apk"],nativeLibraryDirectories=[/data/app/com.promineostudios.ffmpegmodule-1/lib/arm, /vendor/lib, /system/lib]]
  at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
  at com.promineostudios.ffmpegcodec.FFMpegCodec.loadFFMpegBinary(FFMpegAndroidCodec.java:39) 
  at com.unity3d.player.UnityPlayer.nativeRender(Native Method) 
  at com.unity3d.player.UnityPlayer.a(Unknown Source) 
  at com.unity3d.player.UnityPlayer$b.run(Unknown Source)

我认为问题出在我将 lib 导出到 Unity 时,但我不知道出了什么问题。如果有人可以帮助我,我将不胜感激。

谢谢,对不起,我的英语。

【问题讨论】:

  • 我们遇到了类似的问题,想知道您是如何解决这个问题的。
  • 嗨@uchamp,我不知道如何解决它。如果你找到一种方法让它起作用,如果你分享它,我将不胜感激。很抱歉未能为您提供帮助。
  • 您是否尝试过将包含“com.github.hiteshsondhi88.libffmpeg”类的 .jar 文件复制到统一插件文件夹中?
  • 问题解决了吗?我也面临同样的问题。 @RandomCouch 任何帮助将不胜感激。提前致谢。
  • 嗨,我不再从事这个项目,我们没有找到解决方案。对不起

标签: java c# android-studio unity3d ffmpeg


【解决方案1】:

我知道您不再从事 Nestoraj 这个项目,但是我已经找到了解决方案:

  1. 您遇到的错误是由于 UnityPlayerActivity 没有找到 com/github/hiteshsondhi88/libffmpeg/FFmpeg 的源代码,所以为了解决这个问题,您必须将 'com.writingminds:FFmpegAndroid:0.3. Unity 项目的 Assets/Plugins/Android 文件夹中的 2' jar 文件

  2. 这样做并运行项目后,您仍然会在加载 ffmpeg 二进制文件时遇到错误,这是因为它也没有正确打包在 Unity 中,要解决此问题,您需要将项目导出到Gradle/Android Studio,然后在 src/main/jniLibs 目录中,您必须根据每个架构放置 ffmpeg .so 二进制文件,例如 jniLibs/armeabi-v7a/libARM_ARCH.so jniLibs/armeabi/libARM_ARCH.so 等。然后您还必须将 ffmpeg 目标文件放在 src/main/assets 中,并根据每个架构再次放置:src/main/assets/armeabi-v7a/ffmpeg 等。

完成这两个步骤后,您应该能够在 Android Studio 中运行您的项目并在您的 Unity 项目中加载 ffmpeg 二进制文件

【讨论】:

    猜你喜欢
    • 2015-04-28
    • 1970-01-01
    • 2013-07-04
    • 2015-08-20
    • 2015-06-07
    • 2014-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多