2012-01-12 13 views
15

私はAssimpライブラリを共有ライブラリとして構築しました。私はAndroid ndkプロジェクトにそれを含めていますが、うまく構築されますが、ロードすると次のエラーが表示されます。 ネイティブライブラリを読み込めません:My-Native-Activity。Androidのネイティブアクティビティからサードパーティの共有ライブラリを読み込む

(おそらく、ライブラリが含まれておらず、apkとデバイスをチェックしていて、ライブラリがlibsフォルダに追加されていて、/ dataのデバイスにインストールされている/データ/私のアプリ/ 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) 
+0

私は今、この問題に取り組んでいます。共有された.soライブラリがデータフォルダに表示されているのがわかります。しかし、もし私が共有するメインライブラリをコンパイルすると、アンドロイド_mainが呼び出されることはありません。 – Halsafar

+0

Androidで動くように動かされましたか? githubにいくつかのサンプルコードを載せることができますか?アセットディレクトリからの読み込みに問題があります。 Assimpはあなた自身のIOSシステムとIOStreamを実装することができますが、動作させることはできません! Txn! –

答えて

19

サブクラス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に制限されています。

+1

+1は、hasCode = "false"を削除します。私はなぜ私のJavaコードを構築していないのか分かりませんでした:P –

+0

'package comで行われたようにパッケージ名を明示的に参照せずにこれを達成する方法があるかどうかは分かりませんあなたは行頭に行? APKファイルでパッケージ名が強制的に変更されたときにコードが失敗するため、私は尋ねます。ここにJavaのnoob。 –

0

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

urライブラリをur apkファイルに圧縮する必要があります。インストール中にアンドロイドが解凍して入れます/ data/data/urapp/lib /に自動的にコピーされます。

希望する情報は、 System.loadLibraryを使用して

+0

提案していただきありがとうございます。なぜ彼らはそのフォルダに行ったのか分かりませんが、libsディレクトリのapkアーカイブ内にあるeclipseを通して、ndk-buildの一部としてapkファイルにパッケージ化されました。その後apkはadbを使ってインストールされ(そして再びeclipseを介して)、それが終わったところです。私はそれらを見つけるためにadbシェルを使って見つけました...私はさらに調査します。 –

+0

ああ、/ data/data/my-app /に移動し、ls -alをやった。 libsフォルダに/ mnt/asec/my-app/libへのシンボリックリンクがあります。 これを反映するようにメインの投稿を更新します。再度、感謝します。 –

1

は、移動するための方法です。

Androidは自動的に依存共有ライブラリを読み込みません。だから、このような何かをする必要があります。

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

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

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

This questionが該当します。

+0

NativeActivityクラス(これは主な方法ではありません)をサブクラス化しない限り、スタティックブロックのアプローチは機能しません。実行時に必要なライブラリをロードする別の方法が必要ですか? – alexleutgoeb

+0

あなたの写真はめまいになります –

6

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); 
    } 
} 
+0

これは素晴らしいことですし、私のために働く。 1つのnit: 'package com.example.native_activity; 'という行コードボックスの外にあり、私はそれを逃した。このことが重要であることがわかります。それなしでコンパイルされますが、私は次の時間を費やして、クラスがロードされない理由を追いました!私は編集しようとしましたが、少なくとも6文字を変更しない限り、それは私を許さないでしょう。 : - | –

関連する問題