I started Android a week ago and I have a design question.
I have two activities A and B. I'm currently on activity A. In activity A I start a thread that listens to network messages. On receiving start in the background thread over the network, I need to go into activity B.
Question: Can I simply call startActivity(B.class) from the background thread?
If not, I suppose I use a Handler to call startActivity(B.class) from activity A thread.
Question: Will my background thread still continue to execute once activity A, the one that created it is destroyed, provided I take care that there are no dead references?
Eventually I receive a stop message in the background thread, again, over the network. Now I need to go back to activity A (or some other activity).
Question: Should I replace the handler instance in the background thread class with a new handler instance created in Activity B? I reckon I'll have to pass the thread object to activity B when I start it. I'll presumably have to take care of the race condition when switching out the handler instances.
All of this seems... complicated. Is there a more elegant way to achieve this? Services? Loopers? All of this is new and the tools/design choices are a bit confusing.
If you are having multiple Activities then this isn't the ideal way of doing it.
Once Activity destroys your thread will have no more reference though it is running in the background. Use a singleton class to create the thread and register your respective handlers to that class, you will be able to communicate to the activities easily through these handlers.
Related
I have currently the following problem:
I got a server that provides and API via Google Protobuf. A Program (in this case an Android App) can request informations. I have an Activity in Android that will request Informations in the Background via a Runnable, which will then process the network request and dispatch to a function on the mainthread to update the UI with the new informations. Therefore I give the runnable a final interface with the function to dispatch which is implemented by the Activity. Now as the network stuff happens in the background and the UI should not block (e.g. with a Loading Spinner) I dont know what happens when the user switches to another Activity while the Runnable is still active. Will it still dispatch properly even if there is another Activity active? What is good design practice to solve this.
Of course I thought about adding a variable to the Runnable to mark it as dont dispatch, but there still could be race conditions (it gets dispatched while the user hits the back button, which would already have the dispatched function in the queue for the mainthread before marking the Runnable as aborted).
If you need any additional informations, please ask, I am happy to provide them.
I am using volley library to perform network operations. On Application launch, I hit the service, I want to stop all the operations until i get the response from the service.
So i want to perform this synchronously. As I am using Volley which by default works in a separate thread. So how can i do this.
I have created custom Interface/listener to handle this, but does Android provide some way to achieve this.
I have done following.
Splash Activity implements an interface, and it goes to Main Activity after data is loaded
#Override
public void onContainerLoaded() {
//startActivity(MainActivity)
}
Even if you want to, you should definitely never EVER run any network-related task synchronously.
What you can do instead is starting your activity normally, and replace your layout with a progressbar logo, that is set to visibility.gone when your task is completed.
EDIT : By the way, if you are just starting your app and you haven't done anything concrete yet, I would recommend you to use an AsyncTask instead of Volley, which is often causing layer-coupling mistakes.
Use some event bus such as Otto
Create an event, make your main activity subscribe to the event using the event bus, start your operation, display a "Loading..." or something ProgressDialog in your main activity. From your worker thread when it completes send an event to your main activity. Make your main activity close the "Loading" dialog when it receives the event,
I guess a better question would be why you want to force it on the main thread?
As far as I know, volley won't let you do that but you might be able to if you make your own network operation. After Honeycomb, you will get a NetworkOnMainThreadException so you will need to override the policies.
i am using HandlerThread class for thread communications in an Android App.
The main UI thread(Activity) has it own handler,with its handleMessage(Message) overriden to accept message and process it.
HandlerThread 's are created and they use the handler of main thread to send it messages.
Now the complexity arises when fragments come in,
the fragments run on the UI thread(main), so i can't have another handler for the same main thread in fragment class.
so a solution i thought of is to,
Send a reference of handler of main thread to fragment via the argument bundle.
Use that reference to obtain message object and send message in threads created in fragment class.
The activity forwards this message to the fragment via a predefined interface.
So finally, the fragment receives the messages from the threads it started.
would this be a good ,reasonable pattern? or a bad one? any better approach is available?
Please share your knowledge about this.
Thank you,
Regards,
Abhijith
I don't know exactly what you are actually trying to achieve using this pattern
but suggestion is, hosting activity should be considered to manage all operations, It could be done through an interface where hosting activity will receive callbacks from fragments on certain events.
I am writing an SDK that allows a user of the SDK to request data and have it returned to them asynchronously.
To access the SDK I decided to use a Singleton pattern. I do this because they may want to use the SDK from several different activities or fragments and I want each component that uses it to have the same instance. So the user will call MyClass.getInstance() which will return an instance of MyClass to them. Then they can call myClass.doAsynchronousOp(), etc...
One issues I am having is that when a user calls a method on the SDK it will do a bunch of work and I don't want to block the caller's thread. So, the solution I came up with was to create an instance of a HandlerThread when the class is first instantiated. Then when the user calls a method on the singleton class that is supposed to be asynchronous I create a Runnable and run it using the HandlerThread. This seems to work pretty well, but I have a few questions:
1) Let's say the user gets an instance of my singleton and calls one of the asynchronous methods. Now the class is holding a running HandlerThread. When the activity is destroyed is it imperative that I call .quit() on my HandlerThread? If so, I pretty much need to make the user call a method like myClass.unregister() in the onDestroy() method of they're activity which is ok, but I'd rather be able to do it automatically for them. Is it bad practice to not call .quit() on my HandlerThread when the application component holding it gets destroyed?
2) Since this is a singleton I'm noticing that even if the Activity that is holding it is destroyed, the instance can remain in memory. So if the Activity is destroyed and then recreated (device rotation) then my constructor of the singleton doesn't get run again. This is problematic because I setup my HandlerThread in the constructor. If I call .quit() on the HandlerThread when the Activity gets destroyed and then the activity gets recreated, the HandlerThread still exists in the singleton object, but now it's in the Terminated state and I can't use it. Is there a good way around this?
Maybe a more general question: How can I provide asynchronous access to my SDK without running into thread lifecycle vs. android component lifecycle issues?
I have an activity that displays a loading screen while a worker thread is loading my game. While loading the worker thread updates a textview on the activity to display its current status. When finished it will close the loading activity and start the actual game activity.
The worker thread is created in the onCreate() method and is given a newly created handler.
However what happens when the activity is destroyed and restarted e.g. by orientation change? IMHO the onCreate() methods would create a new worker thread while the first one is still loading, so now I got multiple worker threads doing the same.
What is the best way to prevent this and inform the worker thread about the new activity (so it can post its status updates).
Have you tied the DroidFu library? It has a class named BetterAsyncTask that seems to be targeted at getting rid of the problem you're talking about. You can find the library here ( https://github.com/kaeppler/droid-fu ) and an article about your problem and droidfu here ( http://brainflush.wordpress.com/2009/11/16/introducing-droid-fu-for-android-betteractivity-betterservice-and-betterasynctask/ - see the "That Dratted AsyncTask" section).