Global initialization in Android - android

I'm writing some library code distributed as a jar file that developers will need to initialize with an application id before using. Initialization is just a function call, like
MyLibrary.initialize("16ea53b");
The tricky thing is that I am not sure how to instruct developers to make this initialization call. At first I thought a single static initializer block in the main activity would be the easiest way to do it. The problem is a user could enter the application through some other activity or intent, and the main activity would not be loaded. Is there a general way to ensure that a line of code is run at the application's startup regardless of how the application was started?
The initialize call is idempotent so I could just tell people to make this initialization call in every place it could be used, but that would be bothersome.

One easy way is to save something in SharedPrefences when your library code is initialized. And then, wherever you deem important, you can check for this value, and continue if it exists or prompt for initialization or anything (error messages etc). This will also allow your developers to not have to initialize more than once.
Be sure to provide the developers an API to reset this value.
Also, here is a good talk on API design that may help you, by Joshua Bloch.

This sounds like a problem that can be resolved by extending creating a class that extends Application and placing it there, which is global for the entire Application.

Related

Get instance initialized with the new App Startup API

I saw this new API in the Android dev guide,and I wanted to try it out since it looked like a really nice way to initialize components. But looking over the articles and the examples, it makes no sense to me how am I suppose to use this API. I get the first example, in order to use the WorkManager you would first need to call its initialize method, so this new API can handle that for you. But the create method of the Initializer returns an instance of whatever you are trying to initialize. This means that that instance is somewhere available for you to grab. But there is no explanation on how to retrieve that instance later in your code to use it.
So my question is if there was anyone who got around to test this new API, if you could give me an example of how you use the instance that the App Startup API initialized for you. Thanks in advance!
As of now, the library leaves this up to the developer. The point is mainly to add a unified way for libraries to automatically initialize themselves without boilerplate code.
If you are the author of a library using this approach, you are still obligated to provide a way of obtaining these objects.
Edit
I went with the assumption that AppInitializer.getInstance(context).initializeComponent(...) is only used for creating new instances.
However, after having a look at the source code, it turns out instances are cached and immediately returned here if they have been inititialized earlier.
But on the down side, you will need to pass a Context object.
I would also advice to only call it from the main thread, since there is no singleton-style locking in place

How to organize Android App code?

First of all: I am rather new to Android App programming and I have a rather basic question:
Already with the sandbox app I am currently working on, the code in the Activity class get quite huge because all the callback methods / listeners (click listener, callbacks from GoogleApiClient) are in there (either by implementing the respective interface or by creating a private class). But I would rather put those into separate classes.
But the question that I ask myself is this: how would I then be able to access the class attributes of the activity class? Sure, I would then probably create setter/getter, but still I first need a reference to the Activity object. How would I get this?
Thanks and regards!
It's a really wide question, since the answer depends by your project and by your programming style. The first suggestion is: move what you can move in one or more fragment. All stuffs related to google play services can be nicely handled in a fragment for example. Listener and callback are UI related components, so they need a Context of an Activity to work, but you can split your UI (again) with Fragment and keep a piece of logic in a Fragment and another piece somewhere else. If you have some logic that runs in background, then you should consider using Service. I tend to have empty Activities, but this is not a rule.

Android - Determine App Launches and Total Time as Top Activity

I am working on a solution or code that can be embedded inside of an Android APK to track how many times the app has been launched and how long the app has ran for. I know one way to do this is using the ActivityLifecycleMethods in API 14 and in lower versions of Android having code placed in all Activity Lifecycle events or by providing a base Activity class.
1) Is there a way to hook the ActivityLifecycleMethods without the developer having to make any changes to their code outside of dropping additional code into their App?
I believe this answer is no because even with an Enum Singleton it is not loaded until it is referenced. Also the Enum Singleton will go away once the activity is changed since a different class loader is used when activities change.
If I wanted to keep the Enum Singleton around would it be possible to store a reference to the applicationContext and thus it wouldn't be removed when the Activity changes? Is that what google means by
"There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton." on http://developer.android.com/reference/android/app/Application.html
2) I am not a fan of this solution for older API versions. It seems very likely developers could forget to modify their Activity Lifecycle methods or forget to inherit from the created BaseActivity. Are there any other unique solutions for these older platforms? Is there any other approaches that can be done to determine when an activity isn't running? Could any of the following work:
a) User a class loader to ensure the base activity with the proper metrics are always used
b) Implement some type of heart beat. Will a timer stop working if the app is paused or killed? Is there some other way? Could the ActivityManager be used?
You have many Analytic Agents like Flurry to do that.
When ever you want to track an event, you will add it to flurry and inturn it syncs with server after specific time.
You may use the same logic.
Better create a library file with following features:
Start Application
End Application and report time to db.
Track a specific event count and update to db.
Sync the data to server you like to.
Call appropriate events from your app.

How to design library to be accessible from all activities in Android application?

I'm making an Android library which accepts data from the user and does some background work.
Right now, the class which directly interacts with the client app has private objects and public static methods for the client app to call (I chose static over the singleton pattern). It also requires the client app to call an initialize() method the first time they use the library.
This relies on the client app knowing which activity is called first. If their application can start on a number of different activities, that raises an issue.
My options:
Force user to initialize in every activity, and internally maintain whether the library has already been initialized or not.
Follow a different design pattern.
Am I approaching this the wrong way? What is good design practice for a library?
It would be a safe assumption to think that a developer would know what activity will start the application, but if someone decided to use your library in a case where they didn't know, you could make the initialize process somewhat intelligent.
For instance, you could add a boolean flag in the library which keeps track of whether or not it has been initialized. In this way you can have some function that returns this value. If it's true, the library has already been initialized, if not initialize it.
It seems a bit bulky, but it would take nothing more than a simple if statement in the onCreate() function of any potential startup activities, if the library isn't initialized, then initialize it.
Or perhaps make it so that the user can call the initialize function as many times as they want, but keep track of that boolean value. Put the if statement in the initialize function and if it's already initialized, do nothing.
In this way, all the programmer would have to do is place a
someLibrary.initialize();
in each onCreate() method of each Activity in question. Once it's actually initialized, each subsequent call does nothing.
Also, on a side note, it may be worth your while to try to change your code in such a way that an initialize method is not necessary. What exactly does the initialize function do?
I think the Application class is what I was looking for. Thanks amalBit.

Android Application Initialization

I have an application that is driven by a configuration XML: various
app properties are loaded at the app start-time by parsing the XML and
initializing static variables of some class. The data read from this
XML drives different Activities of the application. Presently, I have
called the "parsing and the properties-initialization" from the
onCreate() of my Main Activity.
I have a few questions as regards this case/approach:
Should I invoke the app initialization method from the Application
Object or is the current approach correct? What advantages/
disadvantages do/would we get/have if I choose to invoke it from the
Application object?
Do we really need a static class to store app properties? Or can we have all the properties as a static Collection variable in the application object?
Parsing a XML(~200 nodes) at app load time might take some time(not
sure how long tho); How can I avoid the dreaded ANRs? I am using a
Pull Parser.
Please help me find answers to these questions.
Thank you.
It depends on what you're initializing. Application's onCreate() should be used when you're doing things that need to be done before any part of your app works correctly and only needs to be done once, whereas Activity/Service/etc's onCreate() should be used for things that are needed for that component alone and needs to be done multiple times.
The main concern I have for putting all your initialization into a component is that it will make extending your application more difficult later on. Suppose you want to make some Activity in your application accessible by outside intents - now you've got to either move the initialization code to Application or you have to duplicate initialization code in the non-launcher Activity.
It sounds like you should check out SharedPreferences, especially PreferenceManager.getDefaultSharedPreferences(). The preferences will be stored between sessions and it gives you easy access to simple properties from any Context.
Threading. I find AsyncTask to be the easiest way to accomplish this task; there's a good write-up on it at Google. Alternatively, you could fire up a Service to do this in the background while having a foreground Activity inform the user that you're booting up the app.
The Application object is used for sharing non-persistent state across the application. I don't think you'll need to use an Application class at all. You can do your initialisation in the onCreate() method of the Activity that is called first. To quote the documentation:
The subclass is optional; most applications won't need one. In the absence of a subclass, Android uses an instance of the base Application class.
You don't need to create your own class to store application properties. This is done for you by SharedPreferences.
You should also have a look at the setDefaultValues() method in the PreferenceManager
class as this will set preferences from the data in an XML file. What's nice about this method is that use the readAgain parameter so that the XML is only parsed once - the first time you start up your application - rather than every time.

Categories

Resources