从Android本地活动加载第三方共享库
我已经将Assimp库构建为共享库。我已经将它包含在我的Android ndk项目中,并且构建正常,但是当我加载它时,出现以下错误: 无法加载本机库:My-Native-Activity。从Android本地活动加载第三方共享库
(也许我应该补充一点,当我没有包含库并且已经检查了apk和设备时,我的活动工作正常;库正被添加到libs文件夹并安装在设备的/ data/data/my-app/lib)
我已经做了很多的阅读,看来解决这个问题的唯一方法是在启动我的本地活动之前使用System.loadLibrary加载它们。我想我更喜欢在采取这种方法之前使用dlopen动态加载它们。
我是否正确地假设Android不会自动加载共享库我的本机活动(即我的共享库)依赖于?
我会建立它作为一个静态库,但它已经超过54Mb这将无法正常工作。
这是我的Android.mk: 我试过在LOCAL_LDLIBS中添加-lassimp。我不确定这是否正确,但没有任何区别。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := assimp
LOCAL_SRC_FILES := libassimp.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := native-activity
LOCAL_SRC_FILES := main.cpp
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv2
LOCAL_STATIC_LIBRARIES := android_native_app_glue
LOCAL_SHARED_LIBRARIES := assimp
LOCAL_CPPFLAGS += -march=armv7-a -mfloat-abi=softfp
LOCAL_CFLAGS := $(LOCAL_CPPFLAGS)
TARGET_ARCH_ABI := armeabi-v7a
LOCAL_C_INCLUDES += $(LOCAL_PATH)
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue)
子类android.app.NativeActivity是解决这一问题的最简单的方法。
package com.you;
public class MyNativeActivity extends android.app.NativeActivity {
static {
System.loadLibrary("assimp");
}
}
然后改变你的AndroidManifest.xml
。将android.app.NativeActivity
替换为MyNativeActivity
并删除标记hasCode="false"
。
作为一个方面说明,Android在加载共享库时搜索依赖关系。但搜索范围仅限于/system/lib
。
+1 hasCode =“false”删除。我无法弄清楚为什么它不构建我的java代码:P – 2012-10-31 19:39:04
我猜你不会碰巧知道是否有任何方法可以完成此操作,而无需像package com那样明确引用包名称你;'在开始的路线?我问,因为在APK文件中强制更改软件包名称时,代码当然失败。 Java noob在这里。 – 2015-09-09 01:56:35
1:U无法使用dlopen,因为System.loadLibrary是从Java层加载本地库的唯一方法。 2:Ur库路径看起来不对,位置应该是类似于/ data/data/urapp/lib/
需要将你的库拉到你的apk文件中,并且在安装时,android会将它解压并放入它自动到/ data/data/urapp/lib /。
希望以上信息对你有用。
感谢您的建议。我不知道他们为什么去那个文件夹,但他们被封装到一个apk文件中,作为ndk-build的一部分,通过eclipse(我在apk文件中检查了libs目录)。然后使用adb(再次通过eclipse)安装apk,这就是他们结束的地方。我用adb shell来找到它们,我会进一步调查。 – 2012-01-12 10:40:49
啊,导航到/ data/data/my-app /并做了一个ls -al。 libs文件夹中有一个到/ mnt/asec/my-app/lib的符号链接。 我会更新主帖以反映这一点。再次感谢。 – 2012-01-12 10:49:06
使用System.loadLibrary
是要走的路。
Android不会自动为您加载相关的共享库。所以,你需要做这样的事情:
static {
System.loadLibrary("assimp"); // dependency .so first
System.loadLibrary("native-activity"); // dependent .so second
}
此代码通常会在其中包含本地Java方法(即用关键字native
定义的方法,它通过为本地代码映射)类。由于此代码在static
块中执行,因此它在Java类加载器加载类时执行 - 即在类中的任何代码实际执行之前执行。
你不应该有任何引用assimp
添加到LOCAL_LDLIBS
,因为你已经通过LOCAL_SHARED_LIBRARIES
声明引用assimp
。
This question可能是相关的。
除非您继承NativeActivity类(它不能成为主要方法),否则静态块方法将无法工作,那么在运行时应该有另一种方式来加载所需的所有库,我认为? – alexleutgoeb 2012-02-21 14:54:54
你的照片让我头晕 – 2013-07-11 13:22:06
您想通过java活动启动NativeActivity。这样,您可以在NativeActivity之前加载共享库。
AndroidManifest.xml中:
<application android:label="@string/app_name" android:hasCode="true">
<activity android:name="DummyActivity"
android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="android.app.NativeActivity"
android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden">
<meta-data android:name="android.app.lib_name"
android:value="native-activity" />
</activity>
</application>
DummyActivity。java的:
package com.example.native_activity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class DummyActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
System.loadLibrary("some_shared_lib");
System.loadLibrary("native-activity");
super.onCreate(savedInstanceState);
Intent intent = new Intent(DummyActivity.this, android.app.NativeActivity.class);
DummyActivity.this.startActivity(intent);
}
}
这很棒,适合我。一个nit:行'package com.example.native_activity;'在代码框外,我错过了它。原来这很关键。它会在没有它的情况下进行编译,但是我花了一个小时追赶班级为什么不加载!我试图编辑,但除非我改变了至少六个字符,否则它不会让我。 : - | – 2016-03-13 06:18:05
我正在解决这个问题。我可以看到我的共享.so库出现在数据文件夹中。然而,android_main永远不会被调用,如果我编译链接共享它的主库只是不会加载。 – Halsafar 2012-06-05 23:07:11
你有没有得到assimp在Android上工作?你可以把一些示例代码放在github上吗?我无法从资产目录加载。 Assimp允许实现你自己的IOSystem和IOStream,但是我无法实现它!事务处理! – 2013-06-07 09:11:22