如何构建应用程序动态加载的 APK 和分离库 [英] how to build an APK and separate libraries that the app loads dynamically

查看:22
本文介绍了如何构建应用程序动态加载的 APK 和分离库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简短的总结是:如何构建 APK 和单独的库(我的意思是某种形式的类集(理想情况下,还有资源),例如 JAR、AAR 或 DEX 文件),但不包括那些APK 中的库;相反,应用会在运行时加载它们?

The short summary is: How do I build an APK and separate libraries (by which I mean sets of classes (and ideally, resources too) in some form, such as JAR, AAR or DEX files), but not include those libraries in the APK; instead, the app loads them at run time?

所以我的主要问题是如何构建这样的应用程序(例如 Gradle 配置).如何指定哪些类进入哪些 JAR 或 DEX 文件?我是否要为每个想要结束的 DEX 文件创建一个 Android Studio 模块?

So my main question is how to build such an app (e.g. Gradle configuration). How do I specify which classes go into which JAR or DEX files? Do I create an Android Studio module for each DEX file I want to end up with?

一个密切相关的问题是 Java 代码应该如何加载外部库并在运行时访问它们的类.对于后者,我希望 通过类加载器从 dex 文件访问应用程序的类 会起作用.

A closely related question is how the Java code should then load the external libraries and access their classes at run time. For the latter, I'm hopeful that the approach shown at accessing to classes of app from dex file by classloader would work.

我已经尝试了 https://developer.android.com 上的说明/studio/projects/android-library.html,但这会构建一个确实包含依赖库的 APK.

I've tried the instructions at https://developer.android.com/studio/projects/android-library.html, but that builds an APK that does include the dependency library.

我也尝试过 Multidex (https://developer.android.com/studio/build/multidex.html),但这似乎并没有让开发人员对哪些类进入哪个 DEX 文件有任何控制权,而且,将它们全部打包到一个 APK 中.AFAICT 无法在运行时控制这些 DEX 文件的加载.

I've also tried Multidex (https://developer.android.com/studio/build/multidex.html), but that doesn't seem to leave the developer any control over which classes go in which DEX file, and furthermore, packages them all into a single APK. AFAICT there is no way to control the loading of these DEX files at run time.

这里可能存在XY 问题",所以我最好解释一下背景.

There's a possibility of the "X-Y problem" here, so I'd better explain the background.

我正在为客户构建应用程序.它不会通过应用商店分发,因此无法访问正常的更新机制.相反,客户端希望应用程序能够通过下载自身的新组件来替换旧组件来更新自身,而无需手动旁加载新的 APK.这里的主要动机是更新必须对非技术用户很容易.如果应用程序可以控制更新过程,它可以使其流畅并引导用户.

I'm building an app for a client. It's not going to be distributed through an app store, so it won't have access to the normal mechanism for updates. Instead, the client wants the app to be able to update itself by downloading new components of itself to replace the old components, without a need to manually sideload a new APK. The primary motive here is that the updates have to be easy for non-technical users. If the app can control the update process, it can make it smooth and guide the user.

此外,该应用程序将用于互联网访问稀缺和昂贵的地区,因此客户希望能够以较小的块(例如 2MB)发布应用程序更新,而不是强迫用户重新下载整个应用程序接收一个小的更新.

Moreover, the app will be used in areas where internet access is scarce and expensive, so the client wants to be able to issue app updates in smaller chunks (e.g. 2MB) rather than forcing the user to re-download the whole app to receive a small update.

我应该提到的要求的一个方面是,在运行时要加载的库应该存在于 microSD 卡上.这也有助于在没有互联网访问的情况下分发更新.

One aspect of the requirements I should mention, in case it matters, is that the libraries to be loaded at run time are supposed to live on a microSD card. This can also help with distribution of updates without internet access.

应用程序的当前状态是编写了大约 50%:也就是说,已经发布了几个早期版本,但是现在需要对应用程序进行修改(重组)以满足上述要求以及其他要求.

The current status of the app is that it's about 50% written: That is, a couple of earlier versions have been released, but the app now needs to be modified (restructured) to meet the above requirements, as well as others.

推荐答案

本教程是外部加载 DEX 文件的良好开端.只有三个小源文件(MainActivity.java、LibraryInterface.java、LibraryProvider.java)并将secondary_dex.jar从assets文件夹复制到内部应用程序存储[outdex/dex](教程中也尽可能地说明了互联网)).您必须使用 ant 构建它,因为它使用自定义构建步骤.我试过了,效果很好.值得一看.
Dalvik 和 ART 中的自定义类加载

This tutorial is a good start for external loading of DEX files. Only three small files of source (MainActivity.java, LibraryInterface.java, LibraryProvider.java) and it copies secondary_dex.jar from the assets folder, into internal application storage [outdex/dex] (the internet is also stated as possible in the tutorial). You have to build it with ant, because it uses custom build steps. I tried it, it works fine. Worth a look.
custom class loading in Dalvik and ART


更新此代码已移植到 Android Studio gradle(不需要 ant).https://github.com/timrae/custom-class-loader
测试正常.将 com.example.toastlib.jarSD 卡 复制到 内部应用程序存储 [outdex/dex],(不是 assets 文件夹).(您必须阅读项目中的 README.md 文件来构建它).


UPDATE this code has been ported to Android Studio gradle (no need for ant). https://github.com/timrae/custom-class-loader
Tested ok. Copies com.example.toastlib.jar from the SDcard into internal application storage [outdex/dex],(not assets folder). ( you must read the README.md file in the project to build it).

问:如何添加 Activity,我无法将其添加到清单中?
答:使用片段,它们不需要清单中的条目.

Q: How do I add an Activity, I cannot add it to the manifest ?
A: Use Fragments, they don't need entries in the manifest.

问:一个带有资源的 Jar,旨在添加到现有的项目需要能够将其资源与项目的资源合并自有资源(R.).
A:黑客可用,数据文件...
在可分发的 Jar 文件中打包 Android 资源文件

Q: A Jar with resources that is meant to be added to an existing project needs to be able to merge its resources with the project's own resources (R.).
A: Hacks are available, Data file...
Packaging Android resource files within a distributable Jar file

问:外部文件的权限错误.
A:导入它.

Q: The external file has wrong permissions.
A: Import it.

问:我需要添加使用权限.
A:使用 API23,您可以通过编程方式添加使用权限(但它们仍然需要在 Manifest 中声明,因此 新权限模型对我们来说可能没多大用处.

Q: I need to add uses-permission.
A: Use API23 you can programmatically add uses-permissions (but they still need to be declared in the Manifest, so the new permissions model is probably not much use to us).

此部分适用于更一般的用户(@LarsH 对更新有更具体的要求),上面的示例是 17kb apk 和 1 kb jar.您可以将大部分代码放在一次性 jar 中,更新只需加载一个新的 Apk(然后导入批量代码 jar,以最大程度地减少数据传输).当 Apk 变得太大时,从一个小 Apk 重新开始,所有内容都迁移到另一个 jar(导入 2 个 jar).您需要平衡编码工作量、用户体验、可维护性、可支持性、带宽、android 规则、play store 规则(如果这些词甚至存在的话;O)).

This section is for more general users (@LarsH has more specific requirements about updates), The example above is 17kb apk and 1 kb jar. You could put the bulk of you code in the one-off jar, and updates would involve just loading an new Apk (and then importing the bulk code jar, to minimise the data transfer). When the Apk gets too big, start again with a small Apk and everything migrated to another jar (import 2 jar's). You need to balance coding effort, user experience, maintainability, supportability, bandwidth, android rules, play store rules (if these words even exist ;O)).

注意 Dalvik 已停产

Dalvik 的继承者是 Android Runtime (ART),它使用相同的字节码和 .dex 文件(但不是 .odex 文件),其继承旨在提高对最终用户透明的性能.新的运行时环境首次作为技术预览包含在 Android 4.4KitKat"中,并在以后的版本中完全取代了 Dalvik;Android 5.0Lollipop"是第一个仅包含 ART 运行时的版本.

The successor of Dalvik is Android Runtime (ART), which uses the same bytecode and .dex files (but not .odex files), with the succession aiming at performance improvements transparent to the end users. The new runtime environment was included for the first time in Android 4.4 "KitKat" as a technology preview, and replaced Dalvik entirely in later versions; Android 5.0 "Lollipop" is the first version in which ART is the only included runtime.

这篇关于如何构建应用程序动态加载的 APK 和分离库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆