I need to make a design decision.
From what I read in the android developers site I think I want to implement a Service which launches an AsyncTaskLoader to load data from an OS process in the background.
In the android developers site documentation it says that AsyncTaskLoader can be used in Activities and Fragments, but no mention of Services.
Is it a bad practice to use AsyncTaskLoader in a Service?
If so, how do I collect data from a running OS process in the background? (Note: I need the collection to go on even if the app is closed/destroyed)
Loaders are generally used for UI elements that are created and destroyed relatively often, and need to access the previously queried objects without re-querying every time. A Service won't be destroyed mid load like an Activity or Fragment will, so spawning a new Thread is considered the best practice for loading data in the background in a Service.
Loaders are really for Activities and Fragments, it might make sense to consider an IntentService if you just want a good way to do some work in background threads. Is there something specific that looked useful in AsyncTaskLoader?
Either way you won't be able to keep collecting if your app is destroyed. If your app is destroyed, it's not there to do any work. A Service of some sort is definitely what you want to use to do work in the background though.
Related
I need a shared list of computers made available to all my app's activities. The list of computers needs to be upated by two background tasks of some kind, one that blocks on a socket waiting to receive data, and another task that periodically purges computers from the list. What is the proper Android way of doing this to avoid running into activity lifecycle problems? Specifically,
Can/should I use a singleton to maintain and expose the list to the activities and background tasks? (I'm familiar with thread synchronization issues and am prepared to deal with that.)
Can/should I use the IntentService class (two separate instances for the work I need to carry out) or is there a better way? Do I need to use a BroadcastReceiver in that case or could I still store the list in some common place, like a singleton?
How do I avoid keeping my services running when my application is put in the background?
Updated answer for updated question
You can use a Singleton if you don't have a problem with losing your data when your app get's killed (e.g. when you can rebuild the data on restart). In this case you should check that all your components run in the same process (which is default).
You should not use IntentService for intra-app-communication, however bound Services might be an option here
If you bind services from an Activity and unbind them in onPause, they get automatically stopped (if there are no other bound contexts and they weren't started with startService)
If you think your tasks are too complex to accomplish in the same Service, I would recommend two Services bound by an Activity and backed by a ContentProvider which e.g. can be backed by a database.
Old answer
The issues you expierenced might be a problem of Thread-safety (or the lack of it)
Two Intent Services just to share data within an application is definetly way over the target
A broadcast is the right way to notify components of a change
You might want to take a look at Content Providers
Another solution might be a service, which can be bound by all your other components
You can use Database to maintain the UDP packets with timestamp.
Also periodically check the last sync time from Database to check whether UDP packet is coming or not. Hope you know how to use Database.
For what I understand, the Loader framework is geared towards accessing data stored locally in a ContentProvider / SQLite database. We have the CursorLoader class that handles this use case quite well.
But I wonder if it's practical to use the Loader framework to write classes extending Loader / AsyncTaskLoader to access remote web services (e.g. a REST web service)? I always thought that this framework is a bit too rigid and confusing (lack of proper documentation) for this use case. I prefer handling REST calls in more regular way, using AsyncTasks / Services. But recently I've found some articles that used AsyncTaskLoaders and began to wonder.
So why would anyone use Loaders to access Web Services? The only advantage I see here is that Loaders retain their results automatically. There's no Cursor here to manage afterwards.
Realistically, you probably want to use a networking library like Volley. This has some nice features like request batching and image caching. Nonetheless, for the sake of argument lets compare Service, Loaders and AsyncTask.
Services are the way to go if you want to allow the loading to continue while changing Activities or backgrounding your application. Or, if you want to export your service so multiple applications can use it. Otherwise, use a Loader or AsyncTaskLoader.
Loaders have a few advantages over AsyncTasks.
They are less likely to cause crashes by executing code after the Activity has finished, since they are aware of the android lifecycle.
The design discourages having references to Views or Activities. This reduces the likelihood of forcing the Activity to stay in memory after it has already finished.
Monitor the data source for changes and trigger callbacks when they occur
They have built in caching that can be useful after rotations. For Cursors, the CursorLoader automatically reconnects at the correct position to the last Cursor loaded
However, they also have disadvantages
The API is extremely more cumbersome than AsyncTask. Especially if you care about compatibility with older versions of Android
You are already storing UI state inside onSaveInstanceState(), so using the Loader's causes you to save state in multiple ways. This can be confusing to read and understand. Especially if you end up mixing retained fragments into the mix.
The Loader caches the loaded result, not the UI state that you actually need
I'm assuming you are just reading from web services, not writing. If you are performing updates to a web service and you need to see the service's response, then this changes things. Using an AsyncTask could prevent you from getting the response if the it is received during a rotation.
There are cases where Loader is suitable for webservices: When your server can send push notifications back to client to notify that data is changed.
I was reading a article in Android developer blog Process and Threads which talks about creating new process for specific component of Application. But I failed to understand when will creating a new process in my application becomes a absolute need. Could you please help me understand following doubts I have in this regard.
When as a developer I should feel I need to have a separate process for a Android component/s?
Does introducing a new process has any side effect on application's overall performance?
Any other info is greatly appreciated.
Thanks,
SKU
Having a separate process can be useful if there are components of your application that do not necessarily need to both be running to be useful to the user, and the background task is critical to application "correctness" (either now or in the future). The classic example of this is an app that has a service where the service saves or uploads some data that is critical to your application (critical meaning the only way to get the data back is to have the user re-enter it!). The service might be responsible for doing something like uploading or saving data, while the activity is just the interface for the user. So developers should decouple these two components to prevent problems that may arise from my next point..
Android was designed to run in a resource (especially memory) constrained environment, so processes deemed unimportant are killed periodically to open up memory for important ones by the "low memory killer" (LMK) (if you Google this you'll get tons of information on the topic). Things like foreground processes are understandably given a higher priority since they're currently in use, but they're sometimes killed off as well for reasons like consuming too much memory. Now, imagine you need to save off some data to a database after the user does something in the app and you use a service to do so to ensure that it is done even if the user navigates away from the app. Unless you create the service in its own process the process containing both the activity and the service is likely to be killed since the process belongs to a non-foreground activity.
However it is not always necessary to place the service in its own process, oftentimes simply giving the service its own thread will suffice; it's very application specific. I would only place a service in its own process if it took longer than maybe a few seconds (long enough for the user to navigate away from my application and for the LMK to step in) to perform some task in the background and that task related to the "correctness" of my application (I.E. saving data for later). For something like caching, stick to threads, since if the process gets prematurely killed you can just recreate that data later.
Another reason to have a separate process is if you're running a global service (a service that can be used by applications other than your own) that maybe you provide an interface with via an Activity for configuration.
As for the performance question, there will definitely be a performance hit for something like this. Interprocess communication is not cheap, so you should really only use a separate process if you fit into a specific use case, like the ones mentioned above. Also, there's a certain amount of memory overhead for maintaining a process, so that's another performance hit.
1.)You need to do something on seperate process or thread when you don't want your app to behave slowly. As by introducing threads you force your app not to run on UI thread. Thus making your app responsive to other events. For Example : you can use threads when you have to fetch some data from web service so that it happens in background and doesn't effect your app.
2.)Threads should not be used..We should use AsyncTask or loaders rather in android.
1.) In android 4.0 (and possibly 3.0, not sure though) The device does not let you use the HTTP Agent in the main thread, for this slows the UI..
This is when threads come in handy.
Also with the use of functions that need alot of cpu, if these are run in the UI thread, the UI will lag and not respond until the function finishes.
2.) as stated at 1, it will actually improve the visual performance of your app ;)
I have a multiple Activity application that progresses the user from entering an IP/Host address, to entering some data (another Activity), to viewing a stream of video frames (yet another Activity). I share the Socket between the Activities by creating a singleton. Is this considered a bad pattern to use for an object that cannot be serialized?
I have looked all morning through some of these posts and others through out the web and the best that I can come up with is there is no real easy way, but this one seems very easy to me. The only other approach I think has merit is a custom Application object.
Any insight by people who have worked with singletons across Activities I would really like to hear of any problems I may not be aware of that might get me later... Thanks!!
The downside to your approach is that you cannot rely on the singleton's data structures to always be kept around in memory. Your best bet is to persist information in either SharedPreferences or a SQLite database.
It sounds like your singleton might be a good candidate for a Service. Services are meant for long runnning operations that do not have any UI. Multiple Activities can bind to a service and interact with it. Unlike a singleton, if/when your service gets killed, you will get lifecycle hooks to deal with it appropriately. You can also set it to be restarted when appropriate.
I'm designing an android app which will need to do the following steps:
user pushes a button or otherwise indicates to "sync data".
sync process will use REST web services to move data to and from the server.
the data will be stored locally in a sqlite database.
the sync process should provide status updates/messages to the UI
the user should not be allowed to wander off to other parts of the application and do more work during the sync process.
The first time the sync process runs, it may take 10-20 minutes.
After the initial sync, less data will be transferred and stored and
I expect the process to take 1-2 minutes or less.
I've been doing a lot of reading about android's AsyncTask and various examples of using a Service ... But I don't fully understand the design considerations and trade-offs of choosing one design over the other. I currently have my demo project stubbed out using an AsyncTask. After watching (most of) Developing Android REST client applications: http://code.google.com/events/io/2010/sessions/developing-RESTful-android-apps.html# I'm left confused the design patterns described here feel overly
complex, perhaps because I just "don't get it" yet.
I come from a java, spring, web and desktop application background. Thinking and designing in terms of a handheld device is quite new to me. (What happens when the screen layout is changed? What happens when the phone rings while I'm running a sync?) Taking 2 steps back, if the initial sync IS going to be such a long running process, is there a better way for me to think about the problem->solution, the user experience, the user expectations of an application running on a phone?
Would love to hear from some more experienced android developers out there who have already wrestled with these questions.
In my opinion this is the most tricky/hard part of a mainstream/average Android development. For instance on BlackBerry this is IN TIMES easier.
Definitely you need to use a Service.
AsyncTask does not suit, because it is tightly "bound" to your Activity via a Context handle (otherwise you would not be able to update UI of the Activity from your AsyncTask). However an Activity can be killed by OS once the Activity went in background. An example reason of going to background can be an incoming call - user switches to Phone application so your Activity becomes invisible. In this case (depending on the current RAM state) OS may decide to kill one of the background (invisible to the user) activities.
Some devs workaround this by arranging a static stuff for having a long-running actions inside of. Some recommend to use Application instance. This is because static stuff and Application exist while the whole app process exists. However those are incorrect workarounds. Processes in Android are also may be killed when OS decides it is time to. Android OS have its own considerations about what it can kill and in what order. All processes are devided to 5 levels of "killability". Here is the doc where those levels are specified. It is interesting to read there:
Because a process running a service is
ranked higher than one with background
activities, an activity that initiates
a long-running operation might do well
to start a service for that operation,
rather than simply spawn a thread —
particularly if the operation will
likely outlast the activity. Examples
of this are playing music in the
background and uploading a picture
taken by the camera to a web site.
Using a service guarantees that the
operation will have at least "service
process" priority, regardless of what
happens to the activity.
Your Activity where users initiate a long-running action should show a ProgressDialog to make sure user does not do anything else while the action is running. The guide is here.
Also, you'd most likely want to use the NotificationManager for notifying the user about your long-running action completion (or failure) if your Activity is currently invisible. Here is the NotificationManager info to start from.
There are multiple considerations that you must weigh in order to best decide how to approach your situation. It sounds like you need a good comparison between the two approaches... So here is a list of similarities, and differences and additional considerations that must be taken into account when working on a handheld device.
A Service is a part of your Application that has no UI. It may be called by a UI(Activity) to be started, or may be started by any other component of your Application. When developing, you have the freedom to place it on a different thread, or even run it in a different Task or Process. This allows you to ultimately separate it from your UI. Additionally, you may start the Service to run independently (startService) or bind your activity to it (bindService) depending upon your needs. By using custom Handlers, you can set callbacks to update the UI with your progress. A Service does not necessarily end if a User changes Activities, but may be ended at ANY time by the OS.
A AsyncTask is always instantiated from the UI thread. It only allows specific callbacks, but simplifies the process of multi-threading for the purposes of relatively short transactions (as compared to dedicated separate threaded services) that are inherently tied to actions performed by an Activity. Whenever a User changes Activities, the AsyncTask is put on "pause" and may even die because there is no UI thread for your Activity any longer.
The thing that I would be most concerned about is if the app is going to take 10-20 minutes the first time, I would ASSUME that the User will either change tasks temporarily or set the phone down until it completes (which can cause all of the same complications if the phone sleeps). Given this consideration, a threaded service bound to your activity may be your best choice. To protect your UI, I would make a Progress Dialog for your Activity that receives your progress callbacks. This limits user input in YOUR app and allows your service to continue the way that it needs to. Then override the Activity onResume to check the status of your Service and if it is running. Then you can reset the Dialog immediately.
Given that this is my preferred method, I would also take into account that the OS may kill the App at any time anyway. So make sure to have some way to detect an incomplete or partial sync. Then you may resume automatically when your Activity or Service restarts.
With AsyncTask if the user goes to another Activity you can't transfer that object to the other Activity so it dies. There are tricks you can play when say the user rotates the screen or something like that, but that doesn't extend to general purpose destruction. AsyncTask can randomly die.
Google Sync is run as a Service in the background because syncing can take a while to complete. You might need to follow their path and create your own sync service that you can communicate with. Here is some thoughts how to accomplish that:
http://mylifewithandroid.blogspot.com/2008/01/about-binders.html
You can definitely communicate between Service and Activity, but it's tricky to do it right.
The choice is mainly dependent on the app design. Since both AsyncTask and IntentService stands their ground, what you may want from the app(user experience) is more important and then choose either or both. Some scenarios are mentioned below (mostly what I experienced while developing apps)
Assume apps that have feeds pages - where more than one api calls are made to make the page presentable ( /getFriends, /getDates, /getPictures etc.) you can warp all such api calls to a single AsyncTask with executor which is multithreaded and the sequence of execution doesn't matter. In contrast to IntentService which runs all calls in sequence in a single worker thread. For a high end device with multi-core the call from AsyncTask is more effective. And if you start the AsyncTask on UI thread then updating IU is a piece of cakes(read less boiler plate code). And even if an user leaves the page, with intelligent use of not holding on to the context the app doesn't crash.
Assuming you are trying to write an app which doesn't need the user to be on view/activity/fragment and the total execution time to show something is not mission critical (assume sync service or user notification/alarm) then IntentService is a better choice. (no hassle to start Asynctask on UI thread so that you don't need to write a Handler to force changes on UI etc. etc. and less boiler plate code)
From my experience - write small app for both and compare the pros and cons to get a better idea. (p.s I'd suggest take a look at the iosched app from google to get a better idea - they use both Asynctask and IntentService)
I tend to prefer the IntentService + BroadcastReceiver combo because they give you a really strong degree of control
You definitely have to make sure the UI is running if you are updating something on the screen. ASyncTask crashes were at once reported to be one of the top causes of Android crashes. This can be avoided by keeping some sort of "activityIsAlive" variable and skipping or delaying a UI update if the activity is dead.
The IntentService + BroadcastReceiver combo is a little more resistant to the crash because most tutorials tell you to shut off the BroadcastReceiver onPause or onStop. If you do not do this, again you'll have to turn off the UI update. There's a runOnUiThread command somewhere that will help you do UI updates.
The IntentService + BroadcastReceiver combo is also more extensible. You can create functions and extend BroadcastReceiver to make a more elegant REST processing solution. However, it does require more plumbing vs an ASyncTask
If you do delay the UI update, you may be able to rig it on OnWindowFocusChangedListener. When that function receives true, it means that the UI is alive.
tldr; Make sure the Activity and/or Fragment is alive before updating the UI if you are running something in the background
2015 Edit: check out Loaders as well. A little harder to grasp because there's a lot going on behind the scenes