8

私のAndroidアプリには、4つのライブラリがあります。

libTemplate.so
   depends on libPorkholt.so
libPorkholt.so
   depends on libpng15.so
   depends on liblua.so
   depends on libopenal.so
libpng15.so
liblua.so
libopenal.so

libTemplateに対してリンクする小さなコマンドライン実行可能ファイルを作成し、手動でANativeActivity_onCreateを呼び出すと、リンクして正常に実行されます(LD_LIBRARY_PATHを/data/data/com.mycompany.Template/libにポイントした場合)

アプリを実行すると、次の非常に便利なエラーメッセージが表示されます。

E/AndroidRuntime(13214): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mycompany.Template/android.app.NativeActivity}: java.lang.IllegalArgumentException: Unable to load native library: /data/data/com.mycompany.Template/lib/libTemplate.so

ANativeActivity_onCreateも入力されないので、私の唯一の推測は、リンクと関係があるということです。

私はおそらくこのスクリプトでCMakeを使用していることを言及する必要があります:http : //code.google.com/p/android-cmake/(ndk-buildなしで)ライブラリを自分でビルドします。私はそれを使ってnative-activityサンプルをコンパイルすることができたので、それが機能することを知っています。

また、sonameにバージョン番号が含まれているライブラリがないことを確認しました

私のマニフェスト:

<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.mycompany.Template"
        android:versionCode="1"
        android:versionName="1.0">

    <!-- This is the platform API where NativeActivity was introduced. -->
    <uses-sdk android:minSdkVersion="9" />

    <!-- This .apk has no Java code itself, so set hasCode to false. -->
    <application android:label="Template Porkholt project" android:hasCode="false">

        <!-- Our activity is the built-in NativeActivity framework class.
             This will take care of integrating with our NDK code. -->
        <activity android:name="android.app.NativeActivity"
                android:label="Template Porkholt project"
                android:configChanges="orientation|keyboardHidden">
            <!-- Tell NativeActivity the name of or .so -->
            <meta-data android:name="android.app.lib_name"
                    android:value="Template" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest> 
<!-- END_INCLUDE(manifest) -->
4

4 に答える 4

12

どうやら Android は LD_LIBRARY_PATH を正しく設定するほど賢くはないので、実際のアクティビティを手動でロードする小さなブートストラップ ライブラリを作成することで問題を解決することができました。コードは次のとおりです。

#include <android/native_activity.h>
#include <android/log.h>
#include <dlfcn.h>
#include <errno.h>
#include <stdlib.h>

#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "Porkholt", __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "Porkholt", __VA_ARGS__))

#define LIB_PATH "/data/data/@PH_BUNDLE_ID@/lib/"

void * load_lib(const char * l)
{
    void * handle = dlopen(l, RTLD_NOW | RTLD_GLOBAL);
    if (!handle)
    {
        LOGE("dlopen(\"%s\"): %s", l, strerror(errno));
        exit(1);
    }
    return handle;
}

void ANativeActivity_onCreate(ANativeActivity * app, void * ud, size_t udsize)
{
    LOGI("Loaded bootstrap");
    load_lib(LIB_PATH "libpng15.so");
    load_lib(LIB_PATH "liblua.so");
    load_lib(LIB_PATH "libopenal.so");
    load_lib(LIB_PATH "libPorkholt.so");
    void (*main)(ANativeActivity*, void*, size_t) = dlsym(load_lib(LIB_PATH "lib@PH_APP_TARGET@.so"), "ANativeActivity_onCreate");
    if (!main)
    {
        LOGE("undefined symbol ANativeActivity_onCreate");
        exit(1);
    }
    main(app, ud, udsize);
}
于 2012-09-22T14:53:05.937 に答える
5

Android がマニフェストで指定されたもの以外のライブラリを自動的にロードするとは思わないため、「ダミー」Java クラスを作成して外部依存関係をロードする必要があります。

static {
    System.loadLibrary("openal");
    System.loadLibrary("lua");
    System.loadLibrary("png15");
    System.loadLibrary("Porkholt");
    System.loadLibrary("Template");
}

このセクションは静的であるため、メソッドが呼び出されなくても、クラスがロードされたときに実行されます。

于 2012-09-21T12:29:38.223 に答える
1

これは、API 24 以降には影響しなくなりました (フレームワークの修正については、こちらを参照してください)。ただし、古いバージョンをサポートする必要がある場合は、NativeActivityを拡張し、代わりにマニフェスト ファイルで拡張機能を参照し、回避策としてSdra の回答staticに記載されているブロックを追加します。

于 2017-11-15T20:15:51.577 に答える
0

アクティビティには、おそらく System.Load("libTemplate.so") を呼び出す静的コンストラクターがあります。依存関係の順序に従って他のライブラリをロードする必要があります。

于 2012-09-21T09:22:38.480 に答える