2013-02-19 30 views
3

我有一個共享庫放置在libs/armeabi文件夾中。它使用本機共享庫加載到Android中的速度較慢

System.loadLibrary("library_name.so"); 

庫的大小大約爲3MB。加載時間非常長。它有時會持續近20秒。它阻止了我的GUI。我試圖把System.loadLibrary("library_name.so");放在不同的線程中,但是我的GUI仍然被阻塞。我知道其他應用程序使用更大的.so文件,但加載時間並不那麼大。可能是什麼問題呢?

編輯

3MB是調試版本的大小。發行版本大約800KB,但問題是一樣的。一些額外的信息:

  • 。所以包括我的兩個C++這些環狀連接
  • 運行arm-linux-androideabi-nm -D -C -g library_name.so顯示了大量的函數和變量庫
  • 我不使用LOCAL_WHOLE_STATIC_LIBRARIES
  • 這裏的部分通過使用獲得的arm-linux-androideabi-readelf-tool標題表:
Section Headers: 
    [Nr] Name    Type   Addr  Off Size ES Flg Lk Inf Al 

    [ 0]     NULL   00000000 000000 000000 00  0 0 0 

    [ 1] .dynsym   DYNSYM   00000114 000114 00b400 10 A 2 1 4 

    [ 2] .dynstr   STRTAB   0000b514 00b514 015b0c 00 A 0 0 1 

    [ 3] .hash    HASH   00021020 021020 004d1c 04 A 1 0 4 

    [ 4] .rel.dyn   REL    00025d3c 025d3c 006e98 08 A 1 0 4 

    [ 5] .rel.plt   REL    0002cbd4 02cbd4 000468 08 A 1 6 4 

    [ 6] .plt    PROGBITS  0002d03c 02d03c 0006b0 00 AX 0 0 4 

    [ 7] .text    PROGBITS  0002d6f0 02d6f0 08e6e0 00 AX 0 0 8 

    [ 8] .ARM.extab  PROGBITS  000bbdd0 0bbdd0 00bad0 00 A 0 0 4 

    [ 9] .ARM.exidx  ARM_EXIDX  000c78a0 0c78a0 005b80 08 AL 7 0 4 

    [10] .rodata   PROGBITS  000cd420 0cd420 005cc0 00 A 0 0 4 

    [11] .data.rel.ro.loca PROGBITS  000d46d8 0d36d8 0006e4 00 WA 0 0 4 

    [12] .fini_array  FINI_ARRAY  000d4dbc 0d3dbc 000008 00 WA 0 0 4 

    [13] .init_array  INIT_ARRAY  000d4dc4 0d3dc4 00009c 00 WA 0 0 4 

    [14] .data.rel.ro  PROGBITS  000d4e60 0d3e60 00384c 00 WA 0 0 8 

    [15] .dynamic   DYNAMIC   000d86ac 0d76ac 000100 08 WA 2 0 4 

    [16] .got    PROGBITS  000d87ac 0d77ac 000854 00 WA 0 0 4 

    [17] .data    PROGBITS  000d9000 0d8000 000648 00 WA 0 0 8 

    [18] .bss    NOBITS   000d9648 0d8648 047271 00 WA 0 0 8 

    [19] .comment   PROGBITS  00000000 0d8648 000026 01 MS 0 0 1 

    [20] .note.gnu.gold-ve NOTE   00000000 0d8670 00001c 00  0 0 4 

    [21] .ARM.attributes ARM_ATTRIBUTES 00000000 0d868c 00002d 00  0 0 1 

    [22] .shstrtab   STRTAB   00000000 0d86b9 0000d8 00  0 0 1 
+0

庫中有多少個方法?你如何註冊他們與JNI(通過'RegisterNatives'或給他們'Java_'名字)? – fadden 2013-02-20 01:50:39

+0

@fadden我有5個導出的函數。他們使用RegisterNatives()註冊。這些方法使用我的C++庫中的函數。也許問題可能是整個C++庫包含在我的.so文件中? – sinisha 2013-02-20 08:40:39

+0

@fadden我使用了_auseln_的答案中建議的工具。它表明很多功能都被註冊了。我認爲這個問題的發生是因爲我使用了'LOCAL_WHOLE_STATIC_LIBRARIES'並且不能在沒有它的情況下構建我的項目 – sinisha 2013-02-20 10:15:24

回答

0

問題是一些構造函數中的靜態初始化,需要很長時間才能完成

1

儘量減少共享庫中導出的函數的數量。您可以使用

arm-linux-androideabi-nm -D -C -g library_name.so 

,並檢查該列表是不必要的長時間,並刪除您不使用的那些(聲明它們靜態)。您可以通過$man nm查詢nm的手冊,並閱讀如何使用和解釋它。

如果您需要使用很多功能,請使用RegisterNatives()來註冊您的功能,而不是依靠名稱修改和查找 - 這就是您在給功能名稱如Java_your_path_YourClass_yourFunction時所做的操作。

你也可以嘗試strip(arm-linux-androideabi-strip)你的庫,如果它有符號的話。

爲了避免阻塞UI,可以嘗試儘早在不同的線程中加載共享庫並等待它。

如果暴露靜態庫不是我最終想要的,我不會使用LOCAL_WHOLE_STATIC_LIBRARIES。

LOCAL_WHOLE_STATIC_LIBRARIES

  • 這些都是你希望你的模塊中,以包括但允許鏈接器從它們去除死代碼的靜態庫。
  • 如果您想將靜態庫添加到共享庫並從共享庫中暴露靜態庫的內容,這非常有用。

嘗試修復,而不是周圍的一些構建問題工作這個問題。

+0

我有5個導出的函數。他們使用RegisterNatives()註冊。我應該在哪裏使用'arm-linux-androideabi-nm -D -C -g library_name.so'? – sinisha 2013-02-20 08:43:30

+0

如果你沒有運行它,你怎麼知道你有多少個導出的函數? – auselen 2013-02-20 09:25:01

+1

你可以在ndk中找到nm。 – auselen 2013-02-20 09:25:31