Android预安装NDK应用程序

时间:2011-07-01 10:24:06

标签: android android-ndk

我们正在尝试将NDK应用程序预先安装到/system/app目录中。如果我在ZIP文件管理器中打开apk文件,.so文件位于lib目录中。但是,当我们预安装apk文件时,apk的.so文件不会复制到system/lib目录,导致应用程序在我们在设备中启动时失败。

任何人都可以告诉我应该在Android.mk中为APK文件设置什么,以便从APK文件中提取.so文件并复制到system/lib目录?我们需要将应用程序包含在系统映像中。

非常感谢任何反馈。

谢谢, artsylar

4 个答案:

答案 0 :(得分: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)检查。还需要进行其他一些小的修改,但是一旦你有这个方向,你可能会想出来。希望它有所帮助!

答案 1 :(得分:2)

我认为默认情况下你不能这样做,因为Android的/系统分区是以只读方式挂载的!您需要一个root电话,以便通过以下命令挂载具有写权限的/ system:

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给出的解决方案..

答案 2 :(得分:1)

您必须自己“adb push”.so文件。此外,您不一定要将您的库推入system/lib(该文件夹可能会拒绝您的许可)。大多数将其推送到data/app,然后通过发布

加载
System.load("/data/app/<libName>.so");

答案 3 :(得分:0)

某处可能有文档,但是如果你找不到,我会建议找一个带有相关jni库的预安装应用程序.so并检查android源码或相应的系统镜像或update.zip以查看它是如何处理的。

换句话说,通过示例编程......