2012-09-21 24 views
8

yılında bağımlılıkları ile yerli paylaşılan kitaplık yüklenemiyor:Ben 4 kütüphaneler var benim Android uygulamasında bir yerli aktivite app

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 

Ben ANativeActivity_onCreate libTemplate karşı bağlar ve elle çağrı küçük bir komut satırı yürütülebilir yazarsanız, o bağlar ve Uygulamamı çalıştırırsanız

(Ben /data/data/com.mycompany.Template/lib LD_LIBRARY_PATH işaret varsa) ben bu çok yararlı hata mesajı alıyorum sadece iyi çalışır:

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 

Hatta girmezse ANativeActivity_onCreate, benim tek tahminim o ben muhtemelen o senaryoya sahip CMake kullanıyorum bahsetmeliyiz

bağlama ile ilgili bir şey vardır olmasıdır böylece: ndk- olmadan (kütüphanelerini kendim inşa etmek http://code.google.com/p/android-cmake/ inşa etmek). Yerel etkinlik örneğini onunla derledim, bu yüzden çalıştığını biliyorum.

<?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) --> 
+0

Sizin teziniz nedir? – Ken

+0

Ben sadece yukarıda kaydettim :) –

+0

"ANativeActivity_onCreate'i nasıl manuel olarak çağırdığınızı" söyler misiniz? Bunu C kodunda yaptın mı? – echo

cevap

10

Görünüşe göre Android bir LD_LIBRARY_PATH'yi doğru bir şekilde ayarlayabilecek kadar akıllı olmadığından, asıl etkinliği elle yükleyen küçük bir önyükleme kitaplığı oluşturarak sorunumu çözmeyi başardım.

#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/@[email protected]/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 boostrap"); 
    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 "[email protected][email protected]"), "ANativeActivity_onCreate"); 
    if (!main) 
    { 
     LOGE("undefined symbol ANativeActivity_onCreate"); 
     exit(1); 
    } 
    main(app, ud, udsize); 
} 
+0

Teşekkürler da_petcu21. Yerel kod ile JVM'de kütüphaneler yükleniyor, değerli bir katkıdır;) ... +1 – Sdra

+0

Kod için teşekkürler! – jhasse

+0

Yerel bir etkinlik yükü oluşturmanın tek yolu .so kitaplıkları, ikinci bir yerel etkinlik oluşturmak için kitaplıkları el ile yüklemek ve ilk yerel etkinliği başlatmak olduğunu söylüyor musunuz? Değilse, çözümünüzün nasıl çalıştığını açıklayabilir misiniz? Bu konuda çok az şansa sahip olmak için çok az zaman oldu. –

0

Kişisel Etkinlik muhtemelen System.Load çağıran bir statik Oluşturucu sahip ("libTemplate.so":

Ayrıca, hiçbir kütüphane onun soname'i

Benim apaçık bir versiyon numarası içerir emin oldum). Diğer kütüphaneleri bağımlılık sırasına göre yüklemelidir.

5

Harici bağımlılıkları yüklemek için bir "kukla" Java sınıfı oluşturmak gerekir bu yüzden Android otomatik bildiriminde belirtilen dışındaki kütüphaneleri yükleyecektir sanmıyorum, bu içermelidir:

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

yana Bu bölüm statiktir, sınıfları yüklendiğinde, yöntemleri çağrılmasa bile yürütülür.

+0

evet, sorun buydu ama ben onu Java olmadan çözmeyi başardım. Çözümü göndereceğim –

1

Bu artık API etkiler 24+ (çerçeve düzeltme here bakınız): İşte kod. Ancak, daha eski sürümleri desteklemeniz gerekiyorsa, NativeActivity'u uzatın, bunun yerine manifest dosyasındaki uzantınıza başvurun ve geçici çözüm olarak Sdra's answer'da belirtilen static bloğunu ekleyin.