Android 在不重新安装应用程序的情况下更新本机库

Android 在不重新安装应用程序的情况下更新本机库,android,android-ndk,shared-libraries,Android,Android Ndk,Shared Libraries,我有一个包含两个本机库的应用程序(例如libfirst.so、libsecond.so)。现在是加载库的标准方法 System.loadLibrary("first"); System.loadLibrary("second"); 现在我需要能够在不重新安装应用程序的情况下更新库(不需要update.apk)。 我可以用这种方法加载本机库 System.load("/storage/emulated/0/armeabi/libfirst.so"); System.load("/storage/

我有一个包含两个本机库的应用程序(例如libfirst.so、libsecond.so)。现在是加载库的标准方法

System.loadLibrary("first");
System.loadLibrary("second");
现在我需要能够在不重新安装应用程序的情况下更新库(不需要update.apk)。 我可以用这种方法加载本机库

System.load("/storage/emulated/0/armeabi/libfirst.so");
System.load("/storage/emulated/0/armeabi/libsecond.so");
我认为这是一种不好的做法。 我试图手动复制文件夹getApplicationInfo()中的库。nativeLibraryDir,但系统错误: 打开失败:EACCES(权限被拒绝)

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

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

我认为不包括意外情况

代码签名做两件事。首先,它确保发布应用程序的开发人员与更新应用程序的开发人员相同。其次,它在相关应用程序之间创建信任关系(但此处不适用)。尼古拉·埃连科夫在一次会议上讨论了这个话题

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

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

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


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

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

要安装apk,请执行以下操作:

adb install -r path_to_my_apk.apk
现在,您可以更改代码并重新编译。因此,当您想要更新代码时,可以执行以下操作:

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服务器而这样做的。
它假定应用程序目录中有一个名为lldb的文件夹。如果您正在使用Android Studio进行调试,此文件夹将已经存在

您的Java代码需要确保加载正确的

System.load("/data/data/com.mycomp.myapp/lldb/libmyso.so");
而不是
System.loadLibrary()
,它不会在某个地方的静态初始化块中获取完整路径,类似于加载任何其他块的方式

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