2011-07-01 38 views
9

我們正在嘗試將NDK應用程序預安裝到/system/app目錄中。如果我在ZIP文件管理器中打開apk文件,.so文件位於lib目錄中。但是,當我們預安裝apk文件時,apk的.so文件未複製到system/lib目錄,導致應用程序在設備中啓動時失敗。Android預安裝NDK應用程序

任何人都可以告訴我應該在APK文件Android.mk中設置什麼,以便.so文件將從APK文件中提取並複製到system/lib目錄中?我們需要將該應用程序包含在系統映像中。

任何反饋將不勝感激。

感謝, artsylar

+0

從技術上講,我相信.so文件應該被複制到/data/data/com.yourpackage.name/lib目錄中,但是我在預裝的應用程序中遇到同樣的問題,不會將其複製到APK。 – Devunwired

+0

我們所做的只是使用任何壓縮工具(例如7zip)手動解壓APK這樣的文件。然後,我們創建了一個make文件,在編譯android源代碼時將文件複製到/out/..../system/lib目錄。在我們的例子中,我們希望將它包含在ROM映像中,因爲它是本地應用程序所需要的,這就是爲什麼我們需要將它複製到/ system/lib目錄。 – artsylar

+0

你可以參考這個論壇https://groups.google.com/group/android-ndk/browse_thread/thread/2d08a95b3038e532?hl=ja 他們有同樣的問題,我們的 – artsylar

回答

4

我有同樣的需求,之後重研究2天,我想出了一個解決這個問題。這並不簡單,並且需要您能夠修改Android系統代碼。

基本上PackageManagerService防止系統應用到他們的解壓本地二進制文件(.so文件),除非他們已經被更新。所以解決這個問題的唯一方法就是修改PMS.java(正確命名,因爲試圖解決這個問題讓我處於一種可怕的情緒)。

對系統的第一次開機,我寫一個isPackageNative(PackageParser.Package PKG)檢查各系統封裝機二進制文件的功能:

private boolean isPackageNative(PackageParser.Package pkg) throws IOException { 
    final ZipFile zipFile = new ZipFile(pkg.mPath); 
    final Enumeration<? extends ZipEntry> privateZipEntries = zipFile.entries(); 
    while (privateZipEntries.hasMoreElements()) { 
     final ZipEntry zipEntry = privateZipEntries.nextElement(); 
     final String zipEntryName = zipEntry.getName(); 
     if(true) Log.e(TAG, " Zipfile entry:"+zipEntryName); 
     if (zipEntryName.endsWith(".so")) { 
      zipFile.close(); 
      return true; 
     } 
    } 
    zipFile.close(); 
    return false; 
    } 

這個功能檢查每一個包本機庫,如果有一,我解開它。 PMS在scanPackageLI(....)中檢查。搜索的方法如下代碼:

if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) 

,並添加isPackageNative(PKG)檢查。還有其他一些小的修改需要,但是一旦你有了這個方向,你可能會想出它。希望能幫助到你!

+0

+1即使答案不完整。它有幫助。 – Halsafar

+0

哇謝謝!這是迄今爲止最好的答案,儘管我現在沒有機會嘗試它。但它看起來是最好的方式,所以我會接受這個答案。謝謝! – artsylar

1

你將不得不 「亞行推」 .so文件了。此外,您不必將庫推入system/lib(無論如何,該文件夾可能會拒絕您的許可)。大多數把它推到data/app,然後加載通過發行

System.load("/data/app/<libName>.so"); 
+0

謝謝@ digitalmouse12您的評論。但是,我們需要將應用程序集成到系統映像中,這意味着我們必須在不使用adb的情況下預安裝應用程序。 – artsylar

+0

我發現這篇文章[鏈接](http://groups.google.com/group/android-porting/browse_thread/thread/aff028eff3d680a4/342691bc1145389a?lnk=gst&q=boot+so+apk#342691bc1145389a),它說那裏:「在第一次啓動序列期間(例如,在啓動仿真器或在設備上重置工廠時的數據)之後,系統將掃描/ system/app/ .apk下的捆綁應用程序,並將安裝他們一個接一個「。 – artsylar

+0

這是否也意味着庫文件(* .so)將被解壓縮到/ system/lib目錄?但是爲什麼它還說那裏「與系統捆綁在一起的應用程序_應該將它們的系統庫放置在/ system/lib下」? – artsylar

2

我認爲你不能在默認情況下爲Android的/系統分區做安裝爲只讀!你需要一個根深蒂固的電話,以便通過這個命令寫權限/系統掛載:

mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system. 

所以,如果你有一個根深蒂固的手機,你可以在應用程序中添加以下代碼:

Process p; 
try { 
    // Preform su to get root privledges 
    p = Runtime.getRuntime().exec("su"); 
    // Attempt to write a file to a root-only 
    DataOutputStream os = new DataOutputStream(p.getOutputStream()); 
    // gain root privileges 
    os.writeBytes("mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system\n"); 
    // do here the copy operation you want in /system/lib file, for example: 
    os.writeBytes("mv /sdcard/mylib.so /system/lib/\n"); 

    // Close the terminal 
    os.writeBytes("exit\n"); 
    os.flush(); 

} catch (IOException e) { 
    toastMessage("could not get root access"); 
} 

否則,您必須遵循digitalmouse12給解決方案..

+0

這並不是真正相關的,因爲您正在討論如何修改手機上的安裝,但是海報正在討論在安裝在手機上之前將要安裝的系統映像中包含的內容。 –

+0

謝謝Thanasis。但是,克里斯是正確的。我想知道的是如何預先安裝帶有捆綁的.so文件的預製apk文件到系統映像中。 – artsylar

+0

是的,現在我明白了這個問題,但是我不知道解決方案。如果我找到了一些東西,我會讓你知道! :) –

0

有可能是文件的地方,但如果你不能找到,我會建議識別預裝的應用程序與相關的JNI庫。所以,審查了Android源或相應的系統映像或update.zip看看它是如何處理的。

換句話說,編程舉例...