Plugins architecture for an Android app? [closed]
Asked Answered
C

3

41

THIS QUESTION HAS MOVED TO https://softwarerecs.stackexchange.com/questions/27841/plugins-architecture-for-an-android-app


I want to implement a plugin system for an Open Source app, 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:

For instance, one of the plugins must add a button on a particular screen, and clicking this button increments a value in the app's database. This is not doable with Content Providers and Intents, as far as I know.

I want to avoid making the core app's code complex with tons of hooks everywhere.

The form of the plugin could be a file on the SD card, an app, or anything else.

Cache answered 20/4, 2012 at 2:50 Comment(10)
The app "Doplhin" has a lot of what they call "Add-ons". I have not used the app so I don't know how integrated they really are, but it seems like they have found a plugin architecture that works. Any idea how they do? play.google.com/store/apps/developer?id=Dolphin+Add-ons I guess they do not need to update the core app with new hooks every time they create a new plugin.Cache
I'm not sure but this though dated might be useful dreamincode.net/forums/topic/…Doughy
You'll need to add hooks, otherwise what do the other apps hook into? You might be able to do this with Services and IBindersPhonogram
also check out this similar question(with answer) #5120720Doughy
@Irwin1138: I had seen this page but decided to ask because the question is of very low quality, with no investigation effort. Also, the only answer there is "a nightmare in larger projects", as they say, because they hardcode identifiers.Cache
@JoeSimpson: Look at software that uses Spring's dependency injection: zero pre-defined hooks, but you can redefine anything (write a Java class extending the bean you want to modify, overwrite the wiring parts you want in XML, add new UIs). By the way, there is a Spring-Android project, but it seems more centered on REST services than on IoC/dependency injection.Cache
Are you sure this can't be done using Intents? Do you need their UI elements to be integrated into your layout? The plugin architecture might be easier if you designed it in terms of fragments/dialogs that the third parties can provide or override. If you really need it to integrate into your own layout, you could still support adding pieces of layout via fragments, or expose an API for adding standard View elements in the form of intents like ADD_BUTTON, INSERT_LAYOUT etc. and pass everything back and forth as Parcelables.Ecstatic
@LorneLaliberte: Our plugability needs are very transversal. For instance, one plugin must be able to modify how rendering is performed in various places. Another plugin adds Zeemote (remote control) navigability to all dialogs. Your INSERT_LAYOUT/etc intents idea is interesting, we might use it if no more IoC-style approach is found. Thanks!Cache
Do you have any update on this? did you find a way ?.By the way, great app, I am downloading it right now...Kamin
@FranciscoCorrales: No progress unfortunately, so I am offering a bounty on a smaller-scope question: #23002572Cache
S
9

I have done a framework that works like Robo-guice with some of its primary IoC functions. (Cut down on boilerplate codes that load views/service etc...)

But the core of which, I believe is the solution to your problem, is the ability to load separate APK "plugin" files, that includes "res" as well as <layouts>.xml files. The <layouts>.xml file can be independently inflated by the classes within that APK. That is, you can load a CustomView (that inflates its own <layout>.xml) into an originating/parent App. All this is done without the Parent App APK knowing how the UI was inflated in the plugin APK.

Example of what I mean: I have a Mapping App, the framework will dynamically scan installed APK that matches the "contract" for a "add-on function" plugin, and loads the UI specific to it onto the App's View as a floating panel.

I would say a plugin framework for Android is do-able, as Android has most if not all of the necessary built in APIs to accomplish this.

These are your friends in this area of plugin development for Android:

  1. PackageManager (Scan install packages, aka Plugins)
  2. DexClassLoader (ClassNotFoundException will be a pain if you don't use the correct ClassLoader btw)
  3. Java Reflection
Seger answered 12/8, 2012 at 9:48 Comment(2)
Since this is a pretty common problem, and a hard one, would you mind sharing some snippets of code on how you implemented such solution?Verminous
@jucas Did you find any framework or code-snippet that implements this approach?Alurd
S
7

Where can I find a good example of a plugin architecture?

Roman Nurik from Google has implemented a nice plugins framework in his open source app dash clock. The plugins themselves are Services that extend the DashClockExtension class in the API and are installed as completely independent APK files with their own resources. It's quite a lot of work defining the communication protocol via the AIDL, but it's nice and clean and works very well.

one of the plugins must add a button on a particular screen, and clicking this button increments a value in the app's database.

The parts of the main Layout which can be modified by the plugin will need to be pre-defined by the core app, and exposed via the communication protocol. It should be possible for the plugin to inflate an arbitrary layout, and send it to the main app, which could put that inside a pre-allocated area of it's own Layout.

Stevens answered 27/6, 2015 at 2:12 Comment(2)
Great! I see all hooks have to be defined in advance, right? Or can the example in the 4th paragraph of the question be done easily via a plugin without having to modify the core app?Cache
I updated the answer a bit... I'm not too sure how the callback would need to be implemented in that scenario without spending some time trying it myself, but I guess the onClick property of the button could be set to run a hook with a known name in the main app, or an onClickListener could be programmatically set by the plugin which performs some operation.Stevens
L
5

If you are just going for an increase in modularity, I would recommend using a dependency injection container such as PicoContainer, Guice or Spring.

If you want a light-weight plug-in architecture, then go for Java Plugin Framework (JPF).

It allows you to define extension points, which can be implemented by your modules. The primary job of the plug-in framework is to provide a way that you can bundle these modules (as jars), which are dynamically found by the core application and given as implementations of the extension point.

Linked answered 28/4, 2012 at 12:12 Comment(3)
I added links, you might want to check the URLs indeed point to what you were referring to.Cache
But technically, one user could give a .jar that he downloaded to another user !, what if we don't want this to occur? It's there a way to just insert new code into the app ?Kamin
@FranciscoCorralesMorales: As the original asker of the question, I don't mind users sharing plugins.Cache

© 2022 - 2024 — McMap. All rights reserved.