2011-07-01 60 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看看它是如何处理的。

换句话说,编程举例...