Android应用程序的插件架构?

41

此问题已移至https://softwarerecs.stackexchange.com/questions/27841/plugins-architecture-for-an-android-app


I want to implement a plugin system for 一个开源应用程序, because it has become really large, with many features that only a few users need. Releasing different apps is not a good solution, because userA wants feature7 and feature24 whilst userB wants feature39 and feature24.
Where can I find a good example of a plugin architecture?
Here is what I would like a plugin to be able to do:
- Redefine the layout of a particular screen (加载压缩的XML?) - Redefine a method of a class (加载dex类?, AOP?)
例如,其中一个插件必须在特定屏幕上添加一个按钮,点击该按钮会增加应用程序数据库中的一个值。就我所知,这不能通过内容提供程序和意图来实现。
我希望避免使核心应用程序的代码复杂化,并到处添加大量钩子。
插件的形式可以是SD卡上的文件、应用程序或其他任何形式。

应用程序“Dolphin”有很多所谓的“Add-ons”。我没有使用过这个应用程序,所以我不知道它们到底有多么集成,但它似乎已经找到了一种可行的插件架构。您有任何想法吗?https://play.google.com/store/apps/developer?id=Dolphin+Add-ons 我猜他们不需要每次创建新的插件都更新核心应用程序中的新钩子。 - Nicolas Raoul
2
你需要添加钩子,否则其他应用程序如何连接?您可能可以使用服务和IBinders来完成此操作。 - Joe Simpson
还可以查看这个类似的问题(带答案)https://dev59.com/hW435IYBdhLWcg3w9E9Y - Mikka
1
@Irwin1138:我看过这个页面,但决定提问,因为问题质量很低,没有调查努力。此外,那里唯一的答案是“在更大的项目中是一场噩梦”,因为他们硬编码标识符。 - Nicolas Raoul
你确定不能使用Intents完成这个吗?你需要把他们的UI元素集成到你的布局中吗?如果你设计成片段/对话框的形式,第三方提供或者重写可能会更容易实现插件架构。如果你真的需要将其整合到自己的布局中,你仍然可以通过片段支持添加布局片段,或者公开API以添加标准视图元素,例如ADD_BUTTON、INSERT_LAYOUT等,并将所有内容作为可包含对象传递回去。 - Lorne Laliberte
显示剩余5条评论
3个回答

9
我已经完成了一个框架,它的工作方式类似于Robo-guice,具有其主要的IoC功能。(减少了加载视图/服务等样板代码)
但其中的核心解决方案,我认为是能够加载单独的APK“插件”文件,其中包括“res”以及.xml文件。该.xml文件可以被该APK中的类独立地膨胀。也就是说,您可以将自己膨胀了其<layout>.xml的CustomView加载到源/父应用程序中。所有这些都是在不需要父应用程序APK知道如何在插件APK中膨胀UI的情况下完成的。
我的意思是这样的一个例子:我有一个映射应用程序,该框架将动态扫描已安装的与“插件”功能插件的“合同”匹配的APK,并将特定于其的UI作为浮动面板加载到应用程序的视图上。
我会说,Android的插件框架是可行的,因为Android具有大部分,如果不是全部必要的内置API来完成这项任务。
以下是您在Android插件开发领域中的好朋友:
1. PackageManager(扫描安装包,也称插件) 2. DexClassLoader(如果不使用正确的ClassLoader,ClassNotFoundException将会是个麻烦) 3. Java反射

1
由于这是一个相当常见且困难的问题,您介意分享一些代码片段,以便了解您如何实现这样的解决方案吗? - Julian Suarez
@jucas,你找到任何实现这种方法的框架或代码片段了吗? - Saswat Anand

7

我在哪里可以找到一个好的插件架构的示例?

Google的Roman Nurik在他的开源应用Dash Clock中实现了一个很好的插件框架。这些插件本身是扩展DashClockExtension类的服务,位于API中,并作为完全独立的APK文件安装,并具有自己的资源。通过AIDL定义通信协议相当耗费精力,但这样做既漂亮又干净,而且非常有效。

其中一个插件必须在特定屏幕上添加一个按钮,单击此按钮会增加应用程序数据库中的值。

主布局可由插件修改的部分需要由核心应用程序预定义,并通过通信协议公开。插件应该能够填充任意布局并将其发送到主应用程序,后者可以将其放置在自己布局的预分配区域内。


太好了!我看到所有的钩子都必须事先定义,是吗?或者第四段问题中的示例是否可以通过插件轻松完成而无需修改核心应用程序? - Nicolas Raoul
我稍微更新了答案... 我不太确定在那种情况下回调需要如何实现,而不是花一些时间自己尝试,但我猜按钮的 onClick 属性可以设置为运行主应用程序中已知名称的钩子,或者插件可以以编程方式设置一个 onClickListener 并执行某些操作。 - Tim Rae

5
如果你只是想增加模块化,我建议使用依赖注入容器,例如 PicoContainer, Guice 或者 Spring
如果你想要一个轻量级的插件架构,那么选择 Java Plugin Framework (JPF)
它允许你定义扩展点,这些扩展点可以由你的模块实现。插件框架的主要工作是提供一种方式,让你可以将这些模块(以jar包形式)捆绑在一起,核心应用程序会动态地找到它们,并将它们作为扩展点的实现给出。

我添加了链接,您可能需要检查URL确实指向您所引用的内容。 - Nicolas Raoul
1
但从技术上讲,一个用户可以将他下载的.jar文件给另一个用户!如果我们不希望发生这种情况怎么办?有没有一种方法只是将新代码插入应用程序中? - Francisco Corrales Morales
1
@FranciscoCorralesMorales:作为问题的原始提问者,我不介意用户分享插件。 - Nicolas Raoul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接