onStartListener available for an activity - android

I have a series of activities, one of which is called UserActivity. What I'd like to do is have an object ListenerObject, that listens specifically for when UserActivity starts or stops. That is, I want UserActivity.onStart() to call ListenerObject.onActivityStart() (or some method named similarly).
I know that I can create an observer pattern set of classes to do this, but I'm wondering if there already exists such a framework within the Android API, and, more importantly, an accepted set of use patterns.

You could do this through Broadcasts:
http://developer.android.com/reference/android/content/BroadcastReceiver.html
http://developer.android.com/guide/components/intents-filters.html
In a few ways...
1) Have both activities receive and start from the same intent.
2) have activity 1 launch a broadcast to activity 2.

If ListenerObject makes sense as a static singleton you can just call the method on it during onStart() and onStop():
MySingleton.getSharedInstance().onActivityStart();
which would save you some overhead of the other valid methods mentioned.
The Android devs mention static singletons in the context of lazy creation for speed and reduced memory usage quite a bit it seems so it seems like an accepted pattern.

Depends on the required life cycle of the ListenerObject.
Seems like you want it to be around when the UserActivity isn't, but what about when you have none of your Activities on screen?
You could start a Service and then bind / unbind to it in your UserActivity's onStart / onStop. The service would likely stay alive whilst your app was in the background.
You could (un)bind to a service in all your Activities' onStart/Stop and provide an IBinder interface which asks would allow the service to ask the Activity if it is the UserAnctivity. The service would live whilst you navigate the app, but die once you put it in the background or go to another activity that doesn't bind to it (probably not what you want if you're doing something with G+ authentication / in app purchases etc).
You could (like others suggest) create a singleton, which won't die until the Application does, but won't keep it alive either.
You could have an Event Bus where the Listener subscribes to a known event published by the UserActivity.
shrug just some ideas

Related

What is the proper way to unregister Activity lifecycle callbacks?

In the Android Application class you can register/unregister ActivityLifecycleCallbacks, which allow you to monitor Activity lifecycle events in your application all in one place (if you so desire).
Where is the proper place to call unregisterActivityLifecycleCallbacks? I'm registering in onCreate, and was thinking that onTerminate would be the proper place just from the name of the method but the docs say for onTerminate():
This method is for use in emulated process environments. It will never
be called on a production Android device, where processes are removed
by simply killing them; no user code (including this callback) is
executed when doing so.
I don't see any other methods in the Application class where a 'shutdown' type callback is made. Do you even need to unregister?
Simon was right about this. registerActivityLifecycleCallbacks doesn't require a matching call to unregisterActivityLifecycleCallbacks. As described in this SO question you can't detected when your application is being killed. So there is no "logical" place to unregister your callback. And even if there was, your Application instance is killed after the last Activity action takes place, and the killing of your Application kills the mActivityLifecycleCallbacks list which holds the reference to your callback anyway.
TL;DR - Don't worry about calling unregisterActivityLifecycleCallbacks, it's only there if you want to stop tracking Activity actions during your Application's normal lifecycle.

Is there a design pattern for Android that defines how multiple Activites should access a single Service?

I am developing an Android data entry app that saves the entered data to a file. A Service (let's call it FileIOService) is launched using the filename, and loads and saves data that is passed to it from each Activity that the user accesses.
I am trying to make the whole app as robust as possible, and at the moment I feel I need to pay particular attention to the interaction between each Activity and the Service. Here are the issues I can see:
If the Service is killed by the system, it needs to restart and open the file that it had open: I can handle this by using START_REDELIVER_INTENT.
If an Activity is destroyed, for instance by an orientation change, it needs to reconnect to the Service.
The thing is, once the Activity launches the Service, there's a while before the Service finishes opening the file and becomes ready for I/O requests. To address this, in my Activity, I have both:
an inner class subclassing ServiceConnection, with its onServiceConnected() method completed
a private reference to an anonymous inner subclass of BroadcastReceiver, with its handleMessage() method completed. This gets called when the Service sends out a broadcast to indicate it's finished opening its file.
Both of these methods then call a setUpActivity() method that pulls data from the Service. This is where it starts to get ugly. Because onServiceConnected() may run before the file is ready for I/O, and handleMessage() might be called while the Service is not bound to the Activity, I have to make both handleMessage() and onServiceConnected() set boolean flags that can later be checked in setUpActivity(), like this:
if ((fileLoaded && serviceConnected))
{
//access the file data
}
As I said, this feels ugly and awkward, and relies on setting extra boolean variables.
There's another problem - if my Activity launches an external Activity, like the Camera app, upon returning to my app the Service and Activity may both have been destroyed (especially with an orientation change) and the app crashes.
My feeling is that I may be missing some overall pattern that would define how each Activity should relate to the Service, and vice versa, while remaining robust and able to cope with unexpected terminations/restarts.
Let's ignore the fact that I am skeptical that this is a valid use case for a service (a service whose existence is simply to read and write files?).
If the Service is killed by the system, it needs to restart and open the file that it had open: I can handle this by using START_REDELIVER_INTENT.
The service is not "killed by the system". The process is killed by the system. This will eradicate your activities as well as your service.
The one possible exception to this is if the user manually stops the service (and only the service) from Settings, in which case I have no clue what the expected behavior would be. This should be fairly uncommon nowadays, particularly for an app that the user had just been using. Users will be more inclined to use a task manager, such as swiping your app off the recent-tasks list, which will get rid of the entire process, not just the service.
If an Activity is destroyed, for instance by an orientation change, it needs to reconnect to the Service.
Not necessarily:
Bind using the Application context (getApplicationContext()) instead of from the Activity directly
Use a retained fragment to maintain the binding across the configuration change
My feeling is that I may be missing some overall pattern that would define how each Activity should relate to the Service, and vice versa, while remaining robust and able to cope with unexpected terminations/restarts.
This is one of the many reasons why I try to avoid the binding pattern altogether. Use a service for processing commands, sent via startService(), with results (if any) delivered by LocalBroadcastManager, or Otto, or greenrobot's EventBus, or a "real" broadcast Intent, or maybe a Messenger. Particularly when the service is an IntentService, the service nicely cleans up after itself when there is no more work to be done.

Android: Regular UI Updates & Communication Service <-> Activity

So what I'm trying to do is just updating an activity's views in intervals like, say, once per second. In this specific case a handful of buttons, and all I want to change is their text. I've read quite a few questions here addressing the same problem, but I seem to be stuck a little more than other people, and I'm going to blame that on my restricted experience with Android (which actually means, I did not understand the solutions proposed, or was unable to identify the core ideas in the sample code, and that this is actually the first time I'm trying to program for Android).
Since I would like a service to own the data (and its creation), I thought of a callback to the activity, and that's what I've been trying got get my head around for the past few hours. What I do have is a service with onCreate(), onStartCommand() and onDestroy() and basically, that's fine. I registered it in the android manifest file, and succeeded at bringing it to life (I'm logging the lifecycle methods).
But how do I get to
have the Views updated frequently with the data from the service
give the service certain information it depends on (like notifying it of a button event)
Thanks for your help!
Read about Binding to a Service from the official Android docs.
It should answer all of your questions.
Basically, the idea is that you "bind" to a service, and doing that gives you the service object. From there, you can just call the service's methods directly. In your case, you'd probably want a method declared in your service called notifyButton1Pressed() or something similar.
To refresh the Activity's views in an interval, use a TimerTask and a Timer. Those are pretty self-explanatory if you research them via Google.
In order to update your activity from service, you have to register an BroadcastReceiver in your activity. In the receiver you do your update, and in the service, you have to sendBroadcast to your activity. And information between activity and service you could send through Intent which is sent by sendBroadcast.
There is actually a pretty simple way to update an activity from within itself using a Timer and a android.os.Handler. The idea is to give the activity an interface (e.g. IUpdateable) that exposes an update method. Then extend the TimerTask to take (Handler, IUpdateable) as arguments and keep references to it. In the TimerTask's run() method, call e.g. updateableActivity.update(). In the activity, instantiate a Timer and schedule new UpdateTask(new Handler(), this);.
This way you have an actually reusable approach (using an interface makes this easy to implement in any activity). If this was unclear, have a look at this gist.

How can I bind two Android Activities to one Service?

I would like to ask for some example, where two different activities (a button in the first activity opens a second activity), are communicating with one service (AIDL, etc.).
I've tried many different tutorials, but they are only about how to make one activity → one service.
This is probably old, but I'll try to answer it anyway...
In Android, seeing as only one Activity can bind to a Service at a time, and only one Activity can be shown at a time, there isn't any real reason to want to bind two Activities at a time.
But, if you'd like, the best solution is to bind the Service in the onResume() method, and unbind it in the onPause() method. This allows you to give two unrelated Activities access to the service, while only having one bound at a time.
Each Activity is responsible for binding and unbinding from the Service. This is normally done in onResume / onPause, or onStart / onStop, depending on your requirements. One Activity cannot bind another Activity to a Service. That's just the way it is. :)
You can do it by using Messenger that provide IPC communication without using AIDL. This is how you can bind multiple activities to a service.
If you need your service to communicate with remote processes, then
you can use a Messenger to provide the interface for your service.
This technique allows you to perform inter-process communication (IPC)
without the need to use AIDL.
Have a look at this link. When you see the code, you will find a switch case within a Handler. This will cater to the multiple requests that you will send from you multiple activities/components.

Slickest way to use BroadcastReceiver in a singleton and more

I have a singleton which stores some prudent information about the user of my application. At the moment, it stores the user's login and the user's location.
1)
The location is found via a Service. At the moment, the Service references my singleton directly to stuff the longitude and latitude into it. I would like to use a BroadcastReceiver to send a broadcast that the singleton hears and uses to update the values, instead.
However, to register the BroadcastReceiver, I need a Context in my singleton. What is the slickest way to achieve what I'm wanting. Is BroadcastReceiver possibly not the appropriate object?
2)
Also, what problems am I looking at with using a singleton? I assume that Android will possibly reclaim this memory at any given time (which would obviously be bad); so how can I prevent that? Would passing in the application's Context and storing it in a member variable thwart this?
The Android documentation states: "But, the life cycle of a static is not well under your control; so to abide by the life-cycle model, the application class should initiate and tear down these static objects in the onCreate() and onTerminate() methods of the Application Class," but I'm not entirely sure how to accomplish this.
However, to register the BroadcastReceiver, I need a Context in my singleton. What is the
slickest way to achieve what I'm wanting. Is BroadcastReceiver possibly not the appropriate > object?
The "slickest way" is to not do what you are doing. Please only register a BroadcastReceiver from an Activity, Service, or maybe an Application. You must unregister this BroadcastReceiver when the Activity, Service, or Application is destroyed.
I assume that Android will possibly reclaim this memory at any given time (which would
obviously be bad); so how can I prevent that?
You don't. Android reserves the right to terminate your process at any time (e.g., to reclaim memory). Task killers on Android 2.1 and previous will terminate your process at any time. Once all components of your application are destroyed, Android may recycle your process at any time, clearing out your heap at the same time. And so on.
Only put things in memory that you don't mind losing.
It is best to think of your "application" as a basket of loosely-coupled components, not as a monolithic entity.
Would passing in the application's Context and storing it in a member variable thwart
this?
No.
The Android documentation states: "But, the life cycle of a static is not well under your
control; so to abide by the life-cycle model, the application class should initiate and
tear down these static objects in the onCreate() and onTerminate() methods of the
Application Class," but I'm not entirely sure how to accomplish this.
Create a subclass of Application and indicate in the manifest that Android should use it, via the android:name attribute on the <application> element.

Categories

Resources