tags:

views:

3794

answers:

3

Here's the deal: I have an Android application that needs to call a web service every X seconds (currently 60 seconds). This application has multiple tabs and these tabs all need to interact with the data themselves. One is a MapView, one is a ListView and then the third is irrelevant but will need to also get some global data eventually. The issue is that I want my main activity to have a thread that runs in the background, gets the results and then instructs both child activities in the TabHost to update themselves with the latest data. Also, when the user clicks on the tabs and the onCreate/onResume activities fire, I would also like to force a redraw by getting the latest data from the main activity. I'm really at a loss here. I've tried this with a service and some ghetto static methods to pass an instance of the Activities to the Service to call specific functions to update their views whenever the timer fired, but the slowdowns were pretty bad and the code was just ugly ugly ugly. Any suggestions?

edit: So I implemented it as a timer-driven thread in the tabhost activity and then I have timer-driven threads in each child activity that then grab the data (in a synchronized fashion) and update their map/list. It's much faster but still feels slightly hack-ish, especially the part where I'm calling a custom function in the parent activity like so:

((MainActivity)getParent()).getNearbyMatches();

This adds an element of strong coupling that I'm not entirely thrilled with, but from a performance standpoint it's much better than it was. I appreciate the answers that have already been given and will do a bit of research on the content provider front but I'm not sure I want to go back to the service model.

+1  A: 

You can implement your GUI updates in Handlers and register the Handler instances with your download-thread. The download thread then sends messages to the handlers when new data arrives. Essentially this is the Observer Pattern. You can find an example of how to use Handlers here (expand the 'Example ProgressDialog with a second thread' section).

Josef
+2  A: 

Why are you updating all the children activities every time new data is available? That sounds inefficient to me. Update only the activity that is currently visible.

One possible way to do this is through a custom content provider. Let your service update the data source to your activities and get the current visible activity to listen to changes on this content. So basically, your register to the content provider when OnResume is called and unregister when OnPause is called.

As a rule of thumb never store static references of an Activity!! You'll end up with ugly leaks. If it is a must for your application then at least use WeakReferences

Prashast
+2  A: 

So I've found what I believe is the answer: The Application Class. You can extend this class to keep track of global application state. In the AndroidManifest.xml file you can reference your fully qualified custom class in the android:name attribute and it will be instantiated when the app fires up. Any Activity can then call "getApplication()" and it will return the instance of your custom Application class, which you can then tailor to taste.

MattC