更新本机库而不重新安装应用程序

时间:2015-06-01 10:14:32

标签: android android-ndk shared-libraries

我有app包含两个本机库(例如libfirst.so,libsecond.so)。现在是一个加载库标准方法。

System.loadLibrary("first");
System.loadLibrary("second");

现在我需要能够在不重新安装应用程序的情况下更新库(无需更新.apk)。 我可以加载本机库这个方法

System.load("/storage/emulated/0/armeabi/libfirst.so");
System.load("/storage/emulated/0/armeabi/libsecond.so");

我认为这是一种不好的做法。 我试图复制文件夹getApplicationInfo()。nativeLibraryDir中的库,但系统错误:  打开失败:EACCES(权限被拒绝)

在没有更新apk的情况下更新本机库的最佳实践是什么?

2 个答案:

答案 0 :(得分:1)

  

在没有更新apk的情况下更新本机库的最佳做法是什么?

我不相信会有意外情况。

代码签名可以做两件事。首先,它确保发布应用程序的开发人员与更新应用程序的开发人员相同。其次,它在相关应用程序之间创建信任关系(但这不适用于此)。 Nikolay Elenkov在Code signing in Android's security model讨论了这个话题。

如果要更新依赖库,则需要重建APK以证明您有权进行更新。这是上面讨论的代码签名的第一部分。

如果您想更新应用程序的个人副本(而不是发布它),则只需删除现有签名,更新库,使用Debug signing key签名,然后推送到设备。

此外,您可以安全地执行adb install -r <the apk>-r “替换现有应用程序”,它实际上是重新安装。它保留以前的应用程序数据,如数据库。

更新应用时还需要做一些其他事情,比如增加版本号,以便在Google Play中正确处理。但它们与你的问题无关。

答案 1 :(得分:0)

实际上有一种方法可以做到这一点

安装你的apk:

adb install -r path_to_my_apk.apk

现在您可以更改代码并重新编译.so,当您想要更新它时,您可以执行以下操作:

adb push -p path_to_my_so.so /data/local/tmp/libmyso.so
adb shell cat /data/local/tmp/libmyso.so | run-as com.mycomp.myapp sh -c 'cat > /data/data/com.mycomp.myapp/lldb/libmyso.so; chmod 700 /data/data/com.mycomp.myapp/lldb/libmyso.so'
adb shell rm /data/local/tmp/libmyso.so

Android studio正是这样做,以便在调试本机代码时安装lldb服务器 它假设您的app目录中有一个名为lldb的文件夹。如果您正在使用Android Studio进行调试,则此文件夹已经存在。

您的Java代码需要确保使用

加载正确的.so
System.load("/data/data/com.mycomp.myapp/lldb/libmyso.so");

而不是System.loadLibrary(),它不会在某个地方的静态初始化块中占用完整路径,类似于您加载任何其他的.so

如果您的apk非常庞大并且您只想更新二进制文件以便于调试,则此方法非常有用。