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
Related
In the course of creating an android library, I've learned I need to be able to open an activity from a generic library object and have the activity pass back data to the the library object. Normally, I would simply use startActivityForResult and call it a day, but in this case the library object will be using the client application's context. As such, any result would be sent to the client application and not to the library object.
So the flow would be something like this: Client instantiates our library object -> the library object determines it needs to present its own activity and does so -> library's activity returns data to the library object which can continue processing
I've tried a couple of different solutions but none seem to produce the desired results.
fragments - the issue I ran into here is that the fragment is tied to an activity which means it would need to somehow be tied to the client's activity in order for our object to get what it needs. So for our purposes this doesn't make sense to use.
Temporary splash screen - this is the route we're currently leaning towards since a basic splash screen would allow us to leverage our object on an activity we owned which could then call the activities it may need along the way and then return a response to the client's app in the activityForResult. The drawback of this design is that we were hoping to leverage a set of events which the client could code to when we fire them off. However this can be worked around if needed.
Also looked into leveraging the sharedPreferences but the issue there would be that when we returned to the client's activity we'd somehow need to "kick" the library to continue working. We don't want our clients to have to make multiple calls into our library. And spinning off a background thread to "poll" feels like very bad practice in this situation.
So what I'm looking for is whether the 2nd approach is really the only way to solve this or if there is another way in android development which I'm currently unaware of?
The Android SDK for Optimizely includes the method Optimizely.startOptimizelyAsnyc()
However, the only documentation for it exists here and is quite lacking. I can't find any other documentation or mention of it on the web.
I would like to use this method instead of the regular startOptimizely recommended in the quickstart, because I'd like the web request to occur asynchronously instead of relying on the 2.5-second timeout. Are there any risks or downsides to using the async method?
Also, I am not interested in any callbacks. Is it ok to pass in null for the callback listener argument?
So far, I am using this method and passing null for the callback and everything SEEMS to be working smoothly. But I'd like to know for sure if this may cause any unpleasant surprises down the line.
Thank you!
The Optimizely folks answered my question on their community forum post:
https://community.optimizely.com/t5/Mobile-Apps/Android-when-to-use-startOptimizelyAsync/m-p/10906#M120
Null is a perfectly acceptable value for the callback, we're very
careful about handling null inputs on our APIs.
The downside to using the Async start (especially without a listener)
is that you may evaluate live variables or code blocks before
Optimizely has started, which means that those values will be locked
to to the default value, preventing the experiment from starting. I
would recommend using a callback and listening for the
onOptimizelyStarted() event.
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.
I would like to make some automatic UI tests for my Android application using recomended approach ( http://developer.android.com/tools/testing/index.html ). My activity fetches data from server and after getting response it modifies some UI elements. I want to check whether UI is modified properly but I also want to test this issue without connecting to server. I thought about providing mock component instead of object which connects to server on behalf of activity. But how could I in my test cases tell acivity to replace original object with mock object? Do you know any good approches?
I thought about putting a special flag in Intent using setActivityIntent (indicating that mock object should be used) before calling getActivity in my ActivityInstrumentationTestCase2 instance.
But this approach requires adding some if statements in application code what makes code less clear and more complicated.
Do you have any better suggestions? Thanks in advance.
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.