I have a library, say LIB, which exposes the quite a few APIs and classes for use by application developers.
If there are more than one applications that use LIB on the phone, I want only one instance of LIB to be created and running. It is somewhat similar to what Android Platform Services like LocationManager, SensorManager, PackageManager etc.
Specifically, there are two problems that are to be addressed:-
How to make sure that there is only one instance of LIB ?
How to deploy LIB(separate apk/ bundled with every application that uses it, but only one of them creating the library instance at any point of time) etc.
Is there any other way(other than service/AIDL) to make sure that only one instance of LIB runs irrespective of the number of applications using it.
Okay, after spending time on this, here the answers to my questions:-
Q. How to make sure that there is only one instance of LIB ? -
Only through exposing the LIB functionality through a service.
Q. How to deploy LIB(separate apk/ bundled with every application that uses it, but only one of them creating the library instance at any point of time) etc. -
For service, there would be a separate apk(or probably bundled with one of the service client app),
Q. Is there any other way(other than service/AIDL) to make sure that only one instance of LIB runs irrespective of the number of applications using it.
Yes, that would be like LIB is bundled with every application.
But that would need a strong communication protocol between the libraries using intents, so that one of them acts as master, and shares the data with the other libraries. Effectively, the LIB packaged within an apk starts its engine, only if no other instance is running. One way of accomplishing this is using broadcasts and to maintain security, permissions can be associated with the involved broadcast actions.
With the library project, you have a static inclusion of the classes and resources from the library project. Nothing will be running that doesn't need to be.
That can increase the size of your app, but techniques such as ProGuard can remove unused classes from your final .apk.
If you want your library to be running independently of other apps, then it is indeed a service and you should consider what the lifecycle should be (e.g. started by the app, started at boot, etc.).
If your lib contains activities to be run, the Android OS already handles this - the other app just creates an intent and calls out your activity. This is how Android works - apps can share data and workflow between each other seamlessly using intents.
If there are services, it's the same thing - the calling app either interacts with a running service or triggers a service to start.
Library projects handle a lot of issues for most developers, but if you have a really large shared code package you'll want to install as a separate app.
For example, Google Maps is a separate app, but other apps can trigger an intent to load an activity from that app. The same with messaging and other activities that can be handled by different apps.
Related
I'm developing a native application using C/C++.
I need to use name resolution service.
Making JNI calls is an option.
Using an external native library is another option.
However, I'm thinking about the probability of a third option.
As noted here, on devices running Android 10 and higher, this service is provided with a native library (libnetd_resolv.so).
This means, functions that I need rest in this library and I can confirm that.
My question is, can I use this library dynamically and get name resolution service?
I know that Android doesn't allow applications to use system libraries but what if I download this shared object and distribute with my application*, does it work?
If it doesn't, is there a future plan for this to work?
I'm asking because it is so weird to me that I need a function, it resides in my hands, but I have to make JNI calls in order to use it.
* When I embed the shared object in my application, there may be some compatibility problems when new updates are made to the shared object but that's not the point for me, if it works for one Android release it's ok.
Before attempting to add in a third-party library, do check if the existing Android NDK Networking APIs support your use case.
Do be aware of which versions of Android any particular API is supported.
I have an existing Android App that we now want to leverage as an SDK (or whatever is the equivalent on Android, a library?), so that the application could be included in another Android App as a library.
The concept is that we provide a "wrapper" class that customers make calls to, which would then interface with the existing code to do the functions, display stuff and do the work our App generally does.
My hope is to be able to not have to move code around and just create a wrapper/SDK/Library interface which I can just build differently in gradle, and the result of that (a Library object?) would be given to the customer to include into their App.
Hope I am making sense. If you need more info I can give a high level example of what the App is doing.
My scenario
I have to implement a "modular" android app. There is a core module from which I should be able to invoke other modules. Each module provides a different feature to the user. Imagine I am making a city guide, then one module may contain a map with POIs, another one an event calendar and a third one pre-defined city guides. The modules contain views to be loaded in activities of the core module (like dashboards where each module puts its item/picture). They also contain activities which should be invoked (like when a user taps an item on the dashboard). As far as I know, I will need a database and/or preferences only in the core module. The "plug-in modules" use classes (utilities) of the core module, e.g. when connecting to the backend.
My solution on iOS
For iOS, I achieved this with targets in XCode. I have one project and depending on the customer's needs I compile only the relevant modules. It would be even better if the user can install modules whenever he wants, without the need of reinstalling the "core" application.
My problems on Android
In SO, I already found various solutions like library project, switching from Eclipse to Android Studio + something, using package manager and broadcast receiver... But I still don't understand... How is the modularity of an android application to be achieved?
Here are some concrete problems that I see:
Libraries: My modules all use classes of the core module, so they are not independent. I achieve the modularity by using interfaces/inheritance depending on the flexibility that I need.
Broadcast receiver: This seems to be everything else than recommended. See, for example, here or here.
What I need is, at least, to be able to use the same code for delivering app with features A and B to one customer and with B and C to another one. And, until now, I have no idea how to achieve it.
PS: I don't want to use scripting, I am not familiar with that.
I don't see this "modular" app as anything different from one app, with several packages, each containing discrete functionality, that is adapted to some list of settings or external parameter (either provided by the user or you).
My approach would be to have a "main" package. That package would contain the shared functionality you mention above and serve as the hub for your application. I would then create separate sub-packages for the different "add on" functionality. This allows you to still use the code in your main package with a simple import statement. From your description these additional functions should probably be implemented as a Fragment. A Fragment is almost a stand alone application with the exception that it is "hosted" by an Activity. Depending on how these add on functions are used (I cannot tell if they relate to the UI, just background processing etc) you could easily have 3 of 4 different fragments and choose to load only 1 or 3 or 2 of them at runtime.
To control which parts of the code are used I would just set up a simple switching class (it could even be part of the first activity launched, I cant tell from your description above). Here I would check for some setting indicating which parts of the app will be "active." This could be easily defined using SharedPreferences to store a specific configuration, e.g. use A and B, prior to delivering the final project. You would then just initialize the fragments you need and display them either (1) individually in a Fragment layout element or FrameLayout; (2) collectively in some other view structure like a ViewPager.
I follows your links on the BroadcastReceiver and I am still not sure why they are "everything else than recommended." Used correctly a BroadcastReceiver is very useful. I tend to use a LocalBroadcastManager along with a BroadcastReceiver to notify other sections of the app when some AsyncTask, e.g. downloading a lot of data, is complete. These parts of the app can then access a local database or process the information downloaded on their own time. I wouldn't use a BroadcastReceiver to modulate parts of the app if that is what you're looking for. I would instead just use a SharedPreference file to set the configuration at runtime.
If you need modules like facebook sdk or something like that better use library project. If you use Idea or Android Studio there is such thing like Module. If I need some modeles in one app I prefer just put in different packages like com.appname.model, com.appname.ui and so on. Broadcast Receiver isn't about modules. As I know there isn't analog of ios target.
So... I'm trying to create a plugin for one of my apps. This plugin would require several views, images, an activity and a parser for CharSequences... Ideally, this plugin would be downloadable from the Android Market.
I understand how to create a library, but that would need to be included in the application.
I understand how to create an app as a service and just call it via intents, but I need direct access to objects and code that is neither parceable nor serializable.
What I have been looking at is eyes-free TTS. With their implementation, the developer includes a small TTS_library_stub.jar file in their app, which looks like it defines a lot of the necessary classes/objects.
So my question is, how would I go about building something like this and generating this "stub" .jar file, which would be included in my app? I've been trying to work my way through the TTS code, but it's a massive codebase, and I'm having trouble finding what I'm looking for.
Any help would be massively appreciated :)
The service and the app need to have the same sharedUserId in the manifest and be signed with the same key. Then the app and service can share eachothers assests, classloader and even run on the same thread. I have never included part of the GUI in a service, so maybe that is a limitation...not sure.
If there is a limitation, you must be able to work around it. Look at OpenIntents. It is open source, it is a service and you can download that from the Market. It provides a GUI file browser to any app that uses its intents.
Didn't full understand what you needed, but thought this might help.
If you want android library to be downloaded from market, It has to be standalone android application. (not android library project!). Then you can upload it to market, download it to phone and communicate with it via intent(which this library can handle) or service(aidl) or provider(the data from library) and perhaps receiver, but I never used it in that way.
If you would design your app for an OSGi environment like apache felix it might be possible to load libraries at runtime.
In their presentation they described how the whole concept is working.
Since only APKs can be shared in the android market you would need to write your own "update mechanism" which downloads your OSGi bundles (your plugins) and deploys them to felix.
If I needed to build an android SDK that other developers can integrate into their android apps, is jarring my SDK the only way to go about it? As far as I have learnt, jarring has the following considerations:
If your app uses a layout, then you have to create it programmatically. Since jar files cant carry any resources.
The jar will needs to be placed in the lib/assets folder and added to the build path (in Eclipse) -- Learnt here: Android - Invoke activity from within jar
The main app will have to create an Intent object and specify the package and class name in the jar to start the activity.
Any one have other ideas of going about any of the above steps?
Thanks
George
Creating a JAR is, in my opinion, a very bad decision. Android has specific features just for the kind of thing you're looking for. If your JAR:
provides some sort of (structured) data to be used in other applications, use a ContentProvider;
does some backround processing and makes that processing's results available to other applications, use a Service;
provides an Activity that gets some input from the user (or shows some information about something), eventually processes it and returns it to the calling Activity, just create that Activity and any application will be able to start your Activity as long as it's installed on the phone.
If you use one of the three solutions above, third party apps will be able to probe for whether your application is installed and, if not, prompt the user to install it. Only if your application does not fall into one of the three bullet points mentioned above should you use a JAR. Otherwise, using a ContentProvider, Service or Activity provides:
More standardized interaction between components
Better maintainability -- if you update your SDK you won't have to call everyone who uses it and tell them to upgrade.
No duplication -- if you were to provide a JAR and multiple applications that use it would be installed on a device, multiple copies of the JAR would be present on that device, thus using more memory than it has to. If you provide one of the three components mentioned above, one copy will satisfy all applications that need to use it.
Again, these components are specifically designed and provided by the Android OS for creating such SDKs. Please, only use a JAR if you really, really have to. Otherwise, provide a standardized ContentProvider, Service or Activity and document the way it's supposed to be used (i.e. how to use/query/integrate it).