如何在使用Robolectric时加载.so文件?

8

W/Environment: EXTERNAL_STORAGE未定义;回退到默认值

java.lang.UnsatisfiedLinkError: com.autonavi.amap.mapcore.MapCore.nativeNewInstance(Ljava/lang/String;)J
    at com.autonavi.amap.mapcore.MapCore.nativeNewInstance(Native Method)
    at com.autonavi.amap.mapcore.MapCore.<init>(MapCore.java:62)
    at com.amap.api.mapcore.AMapDelegateImpGLSurfaceView.<init>(AMapDelegateImpGLSurfaceView.java:356)
    at com.amap.api.mapcore.AMapDelegateImpGLSurfaceView.<init>(AMapDelegateImpGLSurfaceView.java:318)
    at com.amap.api.mapcore.ak.a(MapFragmentDelegateImp.java:123)
    at com.amap.api.maps.MapView.onCreate(MapView.java:131)
    at com.e.activity.DriverReleaseActivity.initData(DriverReleaseActivity.java:179)
    at com.e.base.BaseActivity.onCreate(BaseActivity.java:29)
    at android.app.Activity.performCreate(Activity.java:5933)
    at org.robolectric.util.ReflectionHelpers.callInstanceMethod(ReflectionHelpers.java:195)
    at org.robolectric.util.ActivityController$1.run(ActivityController.java:122)
    at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:304)
    at org.robolectric.shadows.CoreShadowsAdapter$2.runPaused(CoreShadowsAdapter.java:45)
    at org.robolectric.util.ActivityController.create(ActivityController.java:118)
    at org.robolectric.util.ActivityController.create(ActivityController.java:129)
    at com.enjoytech.ecar.carpooling.activity.DriverReleaseAcitivityTest.init(DriverReleaseAcitivityTest.java:87)
    at com.enjoytech.ecar.carpooling.activity.DriverReleaseAcitivityTest.test(DriverReleaseAcitivityTest.java:79)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

进程以退出码-1结束

它无法加载.so文件。

当我使用时

try {      
    System.loadLibrary("libamapv304");
    System.loadLibrary("libamapv304ex");
} catch (UnsatisfiedLinkError e) {
    e.printStackTrace();
}

它导致了java.lang.UnsatisfiedLinkError: no libamapv304 in java.library.path错误。
我该如何使用.so文件在Roboletric中完成单元测试?

你在启动程序时是否设置了-Djava.library.path?确保它指向包含你的.so依赖项的路径。 - malaguna
我已经完成了。但是它还是出现了一个错误,说需要一个.dll文件。 - caowenhua
如果您正在使用.so库,但错误提示找不到dll,那么我猜您正在使用为Linux编译的库。尝试查找或编译适用于Windows的库,并将其放置在java.library.path路径中。 - malaguna
由于.so文件是由其他公司提供的,因此很难为Windows重新编译它。 - caowenhua
我能在Linux上使用Robolectric吗? - caowenhua
我不会在 Robolectric 测试中加载这样的内容。 - Eugen Martynov
2个回答

4

我将以某种受控方式加载本地库。为简单起见,假设它在应用程序中:

public class NativeLibApplication extends Application {
    ...
    protected void loadNativeLibraries() {
        try {      
            System.loadLibrary("libamapv304");
            System.loadLibrary("libamapv304ex");
        } catch (UnsatisfiedLinkError e) {
            ...
        }
    }
    ...
}

Robolectric可以让您在测试中调整应用程序。您需要在测试文件夹下创建与包相同的TestNativeLibApplication,并禁止加载本地库:

public class TestNativeLibApplication extends NativeLibApplication {
    ...
    @Override
    protected void loadNativeLibraries() {
        //do nothing
    }
    ...
}

它对我不起作用。:(可能是什么原因。我正在使用Realm数据库和Robolectric进行单元测试。 - N Sharma
我已经提出了问题https://dev59.com/PFgQ5IYBdhLWcg3wqFsF?noredirect=1#comment71975589_42413971,请看一下。 - N Sharma

0

支持打包本地库的支持库

摘要

1. 在应用程序代码中禁用load so。

2. 移植动态链接库。

  • 如果您使用的是Linux操作系统,那么最简单的方法就是获取x86-64(根据您的CPU架构)的so文件,并添加依赖的so库(在ndk-bundle、平台文件夹中找到)。

  • 如果您使用的是macOS操作系统,则需要做更多的工作。您应该有本地so库源代码,并在macOS系统下编译它:

``` Bash


.o

cc -c -I/System/Library/Frameworks/JavaVM.framework/Headers *.cpp


get xxx.dylib

g++ -dynamiclib -undefined suppress -flat_namespace *.o -o something.dylib

```

  • Windows 相似。

3. 在您的 RobolectricApplication 中加载 so 库。

最后,运行您的测试用例,完成:

加载 so 测试用例 http://rocko-blog.qiniudn.com/2016-11-27_09-32-15_test_case_success.png

详细信息

示例代码:RobolectricSupportNativeLibs


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接