As part of Jetpack, there is now a library to handle App Startup.
Specifically, you can implement a component initializer for any of your dependencies, apparently ones that use ContentProvider for their initialization, in order to speed up the app startup process.
My question is how should I know which of my dependencies deserves its own component initializer?
Do I need to guess that, for example, WorkManager uses ContentProvider and requires its own component initializer while a different dependency doesn't?
Thanks.
I believe this library is meant mostly for cases when the initialization code can't or shouldn't be accessed from a custom Application class.
For example, On Demand Modules or libraries that don't want to require the user to call an initialize(context) method.
This library is for content providers, because content providers slow down your applications startup time. whenever you use any lib like workmanger or firebase it will autmatically add its own content provider in your android manifest xml file.
you can know which providers added to your manifest from android studio "Merged Manfest" tab
Related
Is using Google AppStartUp Library is a good aproach? Is it really effective and is it ok to add the initialization code of other 3rd party libraries at our content provider i.e workmanager , Firebace etc
According to me moving workmanager content provider code at our provider does not seem feasible. Can Some one help?
The App Startup library provides a straightforward, performant way to initialize components at application startup.
You can provide inject to your Initializer class.
I'm looking into slowly migrating an existing view-based Android app to a Jetpack Compose app. I figure I will take the opportunity to totally refactor the app, so I'm starting the Compose app from a blank slate, and trying to adopt the latest best practices as I go.
I've created a new project in Android Studio, using the "Empty Compose Activity" that's recommended in some of the docs I've read.
The project it creates lacks a MainApplication.kt file, and the manifest jumps straight into MainActivity, which defines only class MainActivity : ComponentActivity()
I note that the Android docs say "There is normally no need to subclass Application. In most situations, static singletons can provide the same functionality in a more modular way." which has me thinking that, as part of this refactor, I might try follow this implicit recommendation and see where it leads.
So my question is, is there anything that must be done in the Application class that would make me regret the structure that Android Studio has given me?
Does Koin dependency injection work fine outside of the main Application class? My app has services which have Room dependency injections I now do in Application class. All of that can be done elsewhere, presumibly in MainActivity?? (All Koin's examples use the Application class for DI!)
Can setting user permissions like location and file access can be done outside Application class??
I know I'm asking for an opinion here, but do you regard it as best practice to not subclass Application if you can avoid it, as the Android docs seem to suggest?
And lastly, is not subclassing the Application class (ie not having MainApplication.kt) somehow related to the new Compose way of building apps?
thanks!
John
The skeleton code that you get from creating a Compose project from Android Studio does not subclass Application because it just gives you the bare essentials to have a functional compose app.
The Application class is still the right place to initialize your dependency injection graph, plus other libraries that need a one-off initialization, like for instance Timber.
Requesting runtime permissions should be done locally, at the time you need those. If you need some permission to start your application from the get go, ask for those in your activity, the Application is not the right place for that.
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.
I started creating a library that will be shared with several projects.
The problem is that the Android documentation is really short about how to handle properly the library projects. I got really stuck dealing with the conflicts between the few classes I have in common in both the main projects and the library project.
I checked the sample from Android (Tic Tac Toe) but it is really too basic to help, but I just remarked that they used the following packages:
The main project: com.example.android.tictactoe
The library project: com.example.android.tictactoe.library
Is the library supposed to be always contained in the main project package? If yes, how to do when several projects have to share the same library project since the main package name belongs to one main project only?
My biggest problem right now is that my app is calling a class from the library project instead of the main project, and I have really no idea what is the best approach to follow.
Thanks!
Update: My question is related to this one: Best practice: Extending or overriding an Android library project class
There are lots of 3rd party libraries available (such as Action Bar Sherlock) and they do not share the same package as yours.
The packages for the library project and the main app project have no requirement of being related in any way.
In some cases it does help having the library as a sub-package of your main app package: this comes from the way you split the project and if the package for your library being a sub-package would help with organising the code, by all means make it a sub-package of your main package; otherwise, don't. It's all about structuring the code in the end.
It is ok for your app to call (actually use would be the work) classes from your library project. That's what libraries are for. They help keep code contained, reusable and decoupled from other pieces of code.
The problem is the other way around: when your library is calling a class from your main project.
The most common approach for Java and Android here is to use an interface: the library provides the interface that the main project implements, then the main project passes an instance of that implemented interface for the library project to use. The best example here would be callbacks. Android provides a set of interfaces (such as View.OnClickListener) that allow you to hook into the system and perform your application's logic (from the application's point of view, the Android classes in the SDK are the libraries).
Other approaches would be providing classes to be extended (this is just like providing interfaces, but it's used when you want to either leave the library user the option of not implementing/overriding all the methods or when you want to keep some base functionality in the object you will be receiving in your library through the use of the final modifier) and reflection (stay away from it as long as possible as it is very error-prone).
Currently I am working on an application aimed to small local businesses, which serves as a template for other applications (other stores). The base application allows local stores to send notifications to their customers, depending on the business context, notifications can be to report promotions, inform a client that he can pick up his order at the store, notices of new products in the store, etc ... What I do is work on the template for each client and then customize the appearance of the application in the background but the functionality is the same for everyone. My problem is that every time we have more businesses interested in the application and the problem arises when I find bugs or want further improvements, and to update the code in each of the applications can be hell (open each project, add the lines code, recompile, etc ...), and also publish new applications involves a great job because I have to change namespaces whole project, change the authority of the content provider, update references to the namespace associated with the template, etc. ...
Is there any way that I provide update and / or add portions of code in the original template and the changes are automatically reflected in all projects generated from the template?
I have understood Apache Ant can help with the compiling process of large project with many dependencies, but could be useful in the context of my problem?
The solution that I can think of right now is to create a project library and then put everything common to projects, including resources and Activities. The problem is that for example the application Content Provider could not go there because I need to have a single authority in the Manifiest defined for each application.
In advance thank you very much for taking the time to read my message. Any help or advice is welcome. Thank you again.
My question is there any way that I provide update and / or add portions of code in the original template and the changes are automatically reflected in all projects generated from the template?
Make the core code be an Android library project, and use that library project in all the customer apps.
The solution that I can think of right now is to create a project library and then put everything common to projects, including resources and Activities.
Correct.
The problem is that for example the application Content Provider could not go there because I need to have a single authority in the Manifiest defined for each application.
Your ContentProvider implementation can go in the library project. Your customer-specific project will need the <provider> element in the manifest, with a unique authority, pointing to the ContentProvider class from the library.