新聞中心
請教android對so庫的加載與調用
android4.x之后已經限制so不能從sdcard加載,但是可以從其他目錄加載.
創(chuàng)新互聯(lián)公司是專業(yè)的平湖網(wǎng)站建設公司,平湖接單;提供成都網(wǎng)站建設、成都做網(wǎng)站,網(wǎng)頁設計,網(wǎng)站設計,建網(wǎng)站,PHP網(wǎng)站建設等專業(yè)做網(wǎng)站服務;采用PHP框架,可快速的進行平湖網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!
so庫不是簡單的改一個字符串就行的.
如果加載成功,調用出錯,那說明確實做了位置判斷,不過真的很少會有這樣的需求,一般常見的是會做包名判斷,自身完整性校驗
android studio 怎么加載庫
首先 在你把需要的文件復制到項目libs文件夾下(如果沒有這個文件夾,自己建一個);
然后再build.gradle的dependencies 里添加依賴;
文件不同添加依賴方式不同,如是arr文件
compile(name: 'XMF-2.0.3-release', ext: 'aar')
如果是jar包compile files('libs/passguard.jar')
當然也可以右鍵項目 選擇open module setting--dependencies--選擇+號添加你的文件
如果還有什么問題,聯(lián)系我
安卓JVM加載so庫流程
好久沒有寫點東西發(fā)了,工作中的事情有點雜,也找不到整塊東西可以寫的。
最近調查了一個問題,稍微追了一下流程,這里記錄一下。
由于我們支持的設備相對比競品,zygote進程多占用了好幾倍的內存空間。通過dump meminfo后發(fā)現(xiàn),我們的設備在so庫,ttf,和unkonwn mmap的內存空間相比競品一共大了20多M,其中so庫多了15M左右。
通過查看zygote進程的smaps,確定了占用空間最大的幾個so庫確實是我們自己的。雖然確定了內存占用大的原因,還是得把這些so庫是加載在zygote進程中的時機確定了才行。
我的第一反應就是在zygote啟動時,加載sharedLibrary()時,把這些庫加載了,于是去看了這部分源碼,并沒有。
通過反復調試以及追蹤源碼,最后發(fā)現(xiàn)是在JVM啟動的過程中加載了這些so庫,這些so庫的配置在“system/etc/public.libraries.txt”下。
這個文件里配置的都是public的so庫,能夠被普通app訪問的。類似的配置文件還有“vendor/etc/”下面的,還有一些其他的配置地方,我沒有深入去看,想要看的盆友可以自己去看源碼或者注釋。
下面我就帶大家一起看看虛擬機加載這些so庫的流程。
調用棧:
frameworks/base/cmds/app_process/app_main.cpp
----runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
frameworks/base/core/jni/AndroidRuntime.cpp
----AndroidRuntime::startVm
---JNI_CreateJavaVM(pJavaVM, pEnv, initArgs)
art/runtime/jni/java_vm_ext.cc
---android::InitializeNativeLoader();
system/core/libnativeloader/native_loader.cpp
----Initialize()
----ReadConfig(public_native_libraries_system_config, sonames, always_true, error_msg)
其中,public_native_libraries_system_config 為 system/etc/public.libraries.txt
這部分流程是在安卓設備開機過程中的,在執(zhí)行ZygoteInit.main()之前會先啟動java虛擬機的,這樣fork其他java進程的時候,java環(huán)境就已經有了,不用再創(chuàng)建虛擬機了。
最后貼一下Initialize()函數(shù):
Android Native庫的加載及動態(tài)鏈接
我們從一個簡單的NDK Demo開始分析。
下面從 System.loadLibrary() 開始分析。
下面看 loadLibrary0()
參數(shù) loader 為Android的應用類加載器,它是 PathClassLoader 類型的對象,繼承自 BaseDexClassLoader 對象,下面看 BaseDexClassLoader 的 findLibrary() 方法。
下面看 DexPathList 的 findLibrary() 方法
回到 loadLibrary0() ,有了動態(tài)庫的全路徑名就可以裝載庫了,下面看 doLoad() 。
nativeLoad() 最終調用 LoadNativeLibrary() ,下面直接分析 LoadNativeLibrary() 。
對于JNI注冊,這里暫不討論,下面看 OpenNativeLibrary() 的實現(xiàn)。
下面看 android_dlopen_ext() 的實現(xiàn)
接下來就Android鏈接器linker的工作了。
下面從 do_dlopen() 開始分析。
find_library() 當參數(shù)translated_name不為空時,直接調用 find_libraries() ,這是裝載鏈接的關鍵函數(shù),下面看它的實現(xiàn)。
find_libraries() 中動態(tài)庫的裝載可以分為兩部分
下面從 find_library_internal() 開始分析。
下面分析 load_library()
下面看另一個 load_library() 的實現(xiàn)
下面分析ELF文件頭以及段信息的讀取過程,也就是LoadTask的 read() ,它直接調用ElfReader的 Read() 方法。
動態(tài)庫的裝載在LoadTask的 load() 中實現(xiàn)。
下面看ElfReader的 Load() 方法
動態(tài)庫的裝載已經完成,下面看鏈接過程。
下面看 prelink_image()
鏈接主要完成符號重定位工作,下面從 link_image() 開始分析
下面以函數(shù)引用重定位為例分析 relocate() 方法
android項目中如何加載已有so庫
1,在項目根目錄下建立文件夾libs/armeabi文件夾
2,將so庫放入libs/armeabi文件夾注意事項:
1,如果采用靜態(tài)注冊的方式請注意C文件中嚴格按照命名規(guī)則Java_packageName_className_method()的方式命名
2,在Android項目中建立同上述命名規(guī)則中packageName中相同的包名,在此包名下建立同上述命名規(guī)則中className相同的類名
3,在className聲明native方法
4,程序中加載so庫System.loadLibrary(data/data/xxx.xxx.xxx/lib/xx.so)或者System.loadLibrary(xx),例如:System.loadLibrary(data/data/com.dtBank.app.service/lib/libjnixcld.so);
android無法加載androidextra庫
Android項目直接在手機上可以運行。但是打包完后會報這個錯誤,通過錯誤信息大概可以看出是混淆文件的問題,然后就加上RX的混淆重新打包就可以運行了。
新聞名稱:android加載庫,android so庫
瀏覽路徑:http://www.dlmjj.cn/article/dssigdd.html