web-dev-qa-db-ja.com

Androidネイティブアクティビティからサードパーティの共有ライブラリを読み込む

Assimpライブラリを共有ライブラリとして構築しました。 Android ndkプロジェクトに含めましたが、正常にビルドされますが、ロードすると次のエラーが発生します:ネイティブライブラリをロードできません:My-Native-Activity。

(おそらく、ライブラリが含まれていないときにアクティビティが正常に機能し、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)
15
mycroft.holmes

Android.app.NativeActivityをサブクラス化することは、この問題を解決する最も簡単な方法です。

package com.you;

public class MyNativeActivity extends Android.app.NativeActivity {

    static {
       System.loadLibrary("assimp");
    }
 }

次に、AndroidManifest.xmlを変更します。 Android.app.NativeActivityMyNativeActivityに置き換え、タグhasCode="false"を削除します。

ちなみに、Androidは、共有ライブラリをロードするときに依存関係を検索します。ただし、検索の範囲は/system/libに制限されています。

19
Alejandro

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);
    }
}
7
nonameentername

System.loadLibraryを使用するのが方法です。

Androidは、依存する共有ライブラリを自動的にロードしません。したがって、次のようなことを行う必要があります。

static {
    System.loadLibrary("assimp");  // dependency .so first
    System.loadLibrary("native-activity"); // dependent .so second
}

このコードは通常、ネイティブJavaメソッド(つまり、ネイティブコードにマップされるキーワードnativeで定義されたメソッド)を含むクラスに入ります。このコードはで実行されるためです。 staticブロックは、Javaクラスローダーがクラスをロードするとき、つまりクラス内のコードが実際に実行される前に実行されます。

LOCAL_LDLIBS宣言を介してassimpをすでに参照しているため、assimpへの参照をLOCAL_SHARED_LIBRARIESに追加する必要はありません。

この質問 関連する可能性があります。

1
occulus

1:System.loadLibraryがJavaレイヤーからネイティブライブラリをロードする唯一の方法であるため、dlopenを使用できませんでした。2:Urライブラリパスが正しくないようです。場所は/のようになります。 data/data/urapp/lib /

ライブラリをapkファイルに圧縮する必要があります。インストール中にAndroidはそれを解凍し、/ data/data/urapp/lib /に自動的に配置します。

上記の情報がuに役立つことを願っています。

0
kevin.gao