1. ホーム
  2. android

[解決済み] System.loadLibrary(...)でネイティブライブラリが見つからない

2022-11-28 04:39:39

質問

の既存のネイティブライブラリを使いたいのですが、どうすればいいですか? 別の Android プロジェクトから利用したいので、NDK ビルドライブラリ ( libcalculate.so ) を私の新しいAndroidプロジェクトにコピーしました。新しい Android プロジェクトで、フォルダ libs/armeabi/ というフォルダを作り、そこに libcalculate.so があります。そこに はありません。 jni/ フォルダがありません。私のテストデバイスはARMアーキテクチャです。

私のJavaコードでは、ライブラリをロードしています。

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

新しいandroidプロジェクトを実行すると、エラーが発生しました。

java.lang.UnsatisfiedLinkError:  ...
nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libcalculate.so"

エラーにあるように、コピーしたネイティブライブラリが/verdor/libや/system/libにないのですが、私の場合どのように解決すればよいでしょうか?

(apkパッケージを解凍したところ、lib/の下にlibcalculate.soがありました)

=====================================更新

また、プロジェクトルート下に jni/ フォルダを作成し、jni/ 下に Android.mk ファイルを追加してみました。Android.mkの中身は。

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libcalculate
LOCAL_SRC_FILES := libcalculate.so
include $(PREBUILT_SHARED_LIBRARY)

次に、プロジェクトルートで、ndk-build を実行しました。その後、ndk-buildによってarmeabi/とarmeabi-v7a/のディレクトリが生成されます(libcalculate.soがフォルダ内に存在します)。

その後、maven buildを実行すると、プロジェクトが正常に構築されました。最終的なapkパッケージの中には

lib/armeabi/libcalculate.so
lib/armeabi-v7a/libcalculate.so

しかし、アプリを実行すると、同じエラーが投げられます。

java.lang.UnsatisfiedLinkError:  ...
nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libcalculate.so"

どのように解決するのですか?

原因を突き止めるために(そしておそらく同時に問題を解決するために)、以下のことを行ってください。

  1. jni フォルダを削除し、すべての .mk ファイルをすべて削除してください。何もコンパイルしないのであれば、これらも NDK も必要ありません。

  2. あなたの libcalculate.so の中にある <project>/libs/(armeabi|armeabi-v7a|x86|...) . Android Studioを使用する場合は <project>/app/src/main/jniLibs/(armeabi|armeabi-v7a|x86|...) となりますが、eclipseを使っているようですね。

  3. APKをビルドして、それを zip ファイル として開き、あなたの libcalculate.so の中にあることを確認します。 lib/(armeabi|armeabi-v7a|x86|...) にあります。 .

  4. アプリケーションの削除とインストール

  5. 実行 dumpsys パッケージ パッケージ|grep yourpackagename を実行して ネイティブライブラリパス または legacyNativeLibraryDir を指定します。

  6. 実行 ls を実行します。 nativeLibraryPath を持っていたか legacyNativeLibraryDir/armeabi で、libcalculate.soが本当にそこにあるかどうかを確認します。

  7. 存在するのであれば、元から変更されていないか確認します。 libcalculate.so 正しいアーキテクチャでコンパイルされているか、期待されるシンボルを含んでいるか、欠落している依存関係はないか、などを確認します。libcalculate.so は readelf を使って解析することができます。

ステップ5-7を確認するために、コマンドラインとreadelfの代わりに、私のアプリケーションを使用することができます。 ネイティブLibsモニタ

PS: .so ファイルをどこに置くか、またはデフォルトで生成するかで混乱しがちですが、ここにまとめてあります。

  • libs/CPU_ABI eclipseプロジェクト内

  • jniLibs/CPU_ABI Android Studioプロジェクト内

  • jni/CPU_ABI AAR内部

  • lib/CPU_ABI 最終的なAPKの内部

  • の内部で、アプリの nativeLibraryPath を、<5.0 デバイスの場合はアプリの legacyNativeLibraryDir/CPU_ARCH の中にあります。

ここで CPU_ABI のいずれかを指定します。 armeabi, armeabi-v7a, arm64-v8a, x86, x86_64, mips, mips64 . どのアーキテクチャをターゲットにしていて、どのライブラリ用にコンパイルされたかによります。

また、ライブラリは CPU_ABI ディレクトリの間で混在していないことに注意してください: あなたが使っているもののフルセットが必要で、その中のライブラリは armeabi フォルダーにある lib は armeabi-v7a デバイスにインストールされません。 armeabi-v7a フォルダを作成します。