首页 文章

Android预安装NDK应用程序

提问于
浏览
9

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

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

任何反馈将不胜感激 .

谢谢,artsylar

4 回答

  • 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)检查 . 还需要进行其他一些小的修改,但是一旦你有这个方向,你可能会想出来 . 希望能帮助到你!

  • 2

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

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

    所以,如果你有一个root的手机,你可以在你的应用程序中添加这个代码:

    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

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

    System.load("/data/app/<libName>.so");
    
  • 1

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

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

相关问题