Android Service Multiple Thread Design - android

A new question about android and services. Currently I'm developing a App that should send images to a server. It should also be possible to send more images parallel.
I made a service that creates for every image a new image. The activity can bind to that service and gather information about the progress. I want to show the current status for every image in a notification (and when the user clicks a notification, an activity with the progress for that image should be shown).
But I get several problems with that approach. There are errors with binding, the notification pending event starts the activity completly new, so I lose information about currently sending images and so on.
Can someone plase tell me, how I could design such a problem in a appropriate way.
thx

I would use a Controller object that is created in your application class.
This controller is the same for all your activities. If an image upload is started the controller creates a new service/thread and monitors it state and shows the notification. Every activity now can ask the controller for the state of its process and show the corresponded information to the user. This way the controller living in the application lifecyle will bind to the service and not the short lived activity
There was a talk from mark brady on droidcon about this you can find the slides on slideshare. It gets interesting in the later part of the slides when the architecture mark used is explained. I fought with the same problem for some weeks and came to the same results and I'm glad that finally some kind of resource exists on the net on this topic.

Related

How do I get Android to dynamically refresh a url

I have used the Udacity Google Developing Android Apps tutorial and other sources to get my application to fetch an XML file in HTTP via an AsyncTask and display it via a ListAdapter.
Now I am trying to eliminate the refresh button and have it update when the app starts, and then at intervals afterwards.
As far as I can tell, even though the code at Udacity creates a Service, it doesn't eliminate the refresh button.
The code at http://www.vogella.com/tutorials/AndroidServices/article.html#exercise_bindlocalservice only refreshes when the list is clicked.
Does anyone have sample code where the list auto refreshes?
yourListAdapter.notifyDataSetChanged();
or you can use activity life cycle to update the activity through onResume() or onStart() if needed! but i guess you are looking for the first answer to refresh ur listAdapter
if your auto means the content will update whenever there are new contents. You should check those new content by yourself , the classical way is set a Timer to check it . After you got the new content , you can use them to update the view .
Update:
See this:http://www.vogella.com/tutorials/AndroidTaskScheduling/article.html
The reason for not using Timer is not because Timer does 'bad things' but Android does, All running task or data will be stopped and recycled by Android's GC at anytime , so the Timer will be terminated at anytime.
If you have a service or an activity in your application which should perform a repetitive task you cannot reply on a TimerTask or similar approaches and control it from your Android component. Activities and services can be terminated at any point in time by the Android system to free up resources.
So , you can rely on AlarmManager or JobScheduler in the tutorials I post above.
All my questions were answered by using the BasicSyncAdapter example from Google.

Holding References to Fragments after the Parent Activity is Destroyed

Application Flow Image (Cannot post directly - not enough reputation yet)
Introduction
We are creating an application that manages our products. We have several types of a products (1) and each type of product has dozens of those type (2) (ex. Videos).
We have an xml files on our website that holds all the information for each product. When a user selects the type of product (1) it reaches out to our website to download the xml file which populates the product list (2). The user then selects the product from the list which then passes the information to the product single activity (3).
Oh philosophy was when creating the application to create a place where the user can download the product and materials connected to it, but have the application manage which products you have downloaded. You download everything you need so when you don't have internet connection you are still able to use the application and view the products you have downloaded.
Problem
Some of the products in our app are fairly large and require an extended amount of time to download. When a user is on the product single activity (3) they can download the products and when a configuration change happens we understand we need to use fragments to maintain the progress bar and text on the button.
! The problem comes in when the user hits the back button.
We don't want to just cancel the download for the user.
It takes quite a while for the download to finish
We want the user to have the ability to download multiple products at once.
Not canceling the ASyncTask actually lets it continue running when the user hits the back button and even allows us to send Toast messages to show that it is still running. The problem comes in when the user navigates back to the activity the UI doesn't show the file is still downloading because we lost the reference to the ASyncTask that is running.
Solution
We are trying to come up with a solution so that the user can back out of the product single activity (3) and come back to it later and see the status of an ASyncTask if it was started earlier. The problem is if the activity is destroyed how do we hold on to a reference to the ASyncTask or Fragment.
The solution to your problem would be to use services. Services in Android are designed to be long running background tasks. Although you can't directly hook into the UI thread from services, you can use Handlers to post to the UI. Your service will stay around as long as they are needed (Android kills them only under low memory conditions and even then tries to stay away from the running ones).
AsyncTask is designed to be used only for short operations. It is possible to use it with some changes to run longer processes but Android prefers to not do it that way. Android specifically tries to steer you to use background threads and processes.
The problems that you are seeing are because AsyncTask (generally being defined from within the activity class) are tied to the Activity itself and maintains a reference to it. But when an activity goes to the background and has remained in the background for some time, the activity may be destroyed and GC'd at which point, the AsyncTask loses its reference to the parent. With services, it will not matter whether your activity is still available or not. You can connect to the service anytime you want and then query the service to find the status of the download.
first of all there are services that do background work even if your app is displayed on the screen or dead.. second of all there are threads that work and work and work..
thirdly there is a methon called onBind that binds an activity to a service..
your SOLUTION??
use threads in services and whenver your activity is called or app is opened
bind it to the service to get what you want...
NOTE: if your file takes some time to download, well then asynctask is not a recommended approach..that is if it takes a hell of a timee..
Hope im helpful...thnks

IntentService android download and return file to Activity

I have a fairly tricky situation that I'm trying to determine the best design for. The basics are this:
I'm designing a messaging system with a similar interface to email.
When a user clicks a message that has an attachment, an activity is spawned that shows the text of that message along with a paper clip signaling that there is an additional attachment.
At this point, I begin preloading the attachment so that when the user clicks on it - it loads more quickly.
currently, when the user clicks the attachment, it prompts with a loading dialog until the download is complete at which point it loads a separate attachment viewer activity, passing in the bmp byte array.
I don't ever want to save attachments to persistent storage.
The difficulty I have is in supporting rotation as well as home button presses etc. The download is currently done with a thread and handler setup.
Instead of this, I'd like the flow to be the following:
User loads message as before, preloading begins of attachment as before (invisible to user).
When the user clicks on the attachment link, the attachment viewer activity is spawned right away.
If the download was done, the image is displayed. If not, a dialog is shown in THIS activity until it is done and can be displayed. Note that ideally the download never restarts or else I've wasted cycles on the preload.
Obviously I need some persistent background process that is able to keep downloading and is able to call back to arbitrarily bonded Activities. It seems like the IntentService almost fits my needs as it does its work in a background thread and has the Service (non UI) lifecycle. However, will it work for my other needs?
I notice that common implementations for what I want to do get a Messenger from the caller Activity so that a Message object can be sent back to a Handler in the caller's thread. This is all well and good but what happens in my case when the caller Activity is Stopped or Destroyed and the currently active Activity (the attachment viewer) is showing? Is there some way to dynamically bind a new Activity to a running IntentService so that I can send a Message back to the new Activity?
The other question is on the Message object. Can I send arbitrarily large data back in this package? For instance, rather than send back that "The file was downloaded", I need to send back the byte array of the downloaded file itself since I never want to write it to disk (and yes this needs to be the case).
Any advice on achieving the behavior I want is greatly appreciated. I've not been working with Android for that long and I often get confused with how to best handle asynchronous processes over the course of the Activity lifecycle especially when it comes to orientation changes and home button presses...
There're a number of ways to solve this. You're right, I think that you obviously need a Service for this scenario to detach the download process from the Activities that may come and go. For this to work, you need to implement some download-queue in this Service, and IntentService gives this behaviour out of the box, so you can go with that. The only drawback that comes to mind with IntentService is that it's not that easy to cancel a job that you previously posted for it.
I wouldn't serialize the downloaded data however, it doesn't sound too efficient, especially not if you're dealing with large amounts of binary data. You could write the downloaded data into an in-memory LRU cache and assign an ID for it by which the Viewer Activity can get a hold of this downloaded data.
You could also use broadcast Intents to signal the Viewer Activity from the Service, that a download with a particular ID is finished. This would ensure loose coupling between the viewing Activity and the downloading Service.
So it would go something like this:
User open message with attachement.
You post a download job for this attachement to the downloader IntentService, and assign a unique ID for this attachement.
When the user click on the attachement, you start the Viewer Acitivty and you pass the attachement's unique ID as a parameter for this Activity.
The Viewer Activity opens, it immediately checks the Cache for the content to show. If it's not yet complete, it shows some loading graphics and waits for the downloader IntentService to shout "xy ID is done" with a broadcast Intent. If xy ID == the ID passed into this Viewer Activity, you get the now-fully-downloaded content from the Cache and present it to the user.
Edit:
As for the cache, you have to make some choices. I think that this is quite a broad topic on its own, so I'll just write some ideas here based on my previous projects.
Above, I only mentioned an in-memory LRU cache. This would live in a custom Application object, or as a Singleton. Which is using the evil global state, but I think it's reasonable in a situation like this. The advantage is that you don't need to serialize the downloaded data anywhere: the download finished, you have the content in memory and you can access it immediately from the Viewer Activity. The drawback is, that this data will be available only as long as it's not removed from this cache OR the system doesn't kill your application's process because of low memory conditions.
To avoid re-downloading data in case you lost the contents of this volatile in-memory cache, you need to add a persistent layer for it. E.g. writing the downloaded data to the application's cache directory. This brings the overhead of writing the downloaded data to disk, but at least you'll be able to access it later, even if the system kills you process. You may combine this persistent cache with the in-memory cache using a 2-level cache approach, or you may choose either one. I recommend to check out some widely used image downloader libraries that implement this behaviour for inspiration, e.g. Universal Image Loader.
You use an IntentService to go off, do work, and then post it in some persistent storage. To communicate with an Activity, you can use a broadcast receiver in the Activity and send broadcast Intents from the IntentService.
Rotation and home button presses have no effect on an IntentService, as long as it is still doing its work, but a rotation will do a reDraw, and the home button will pause the Activity. For those reasons, you should avoid doing asynchronous work in an AsyncTask unless it doesn't have to complete and doesn't have to persist.
Messages are for Handlers, not for components. The basic affordance for transmitting information through the system is Intents and broadcast Intents.
An IntentService simply handles the work of turning an Intent into a Message, creating a new HandlerThread, putting the Message into the HandlerThread's MessageQueue, and firing off the Looper. The run() that gets executed on the background thread is whatever's in onHandleIntent() (this is a bit of a simplification).

Android background thread that updates the UI in multiple activities

I'm very new to Android, this is my first app. I'm just looking for someone to point me in the right direction.
I am building an app that will query a server over tcp/ip every minute. I would like to show the status of this server (up/down) at the top of every activity/screen.
My questions are:
1) What should I use to continuously ping a server in the background across multiple activities? For instance, is there a way to spawn a thread from one activity in such a way that it will continue even if the user goes to a different screen?
2) How can I allow this thread to update a status label on whatever screen the user happens to be viewing?
Use services. Please get familiar with documentation first.
You can use service binding or local broadcast messaging to notify your current/front activity about changes from your service

Android StartActivtyForResult() from a Service

First I'm sorry for my english that is not so good :).
I am facing a problem to develop my app.
That is a general architecture scheme of my solution.
http://i.stack.imgur.com/ooTmE.png
To be quick, the app has to decode code bare but with two possible ways:
using exernal device (The constructor provides a sdk containing an android Service to communicate with the device),
use the camera of the mobile using the library Zxing which is possible to manage it with intent.
The goal of my own service is to manage some business code and make transparent the choice of the tool for the user.
I believed that was a good solution but I wanted to implement it and I had different problems.
My main trouble is that I cannot execute StartActivityForResult inside the service.
Do somebody have any suggestions for my problem whether a change in the architecture or a solution for the main problem?
#Laurent' : You have totaly right my service acts as an API adapter.
I will try to make the expected behaviour more clear.
I have an app that needs to recognize (real) objects which have QR codes on their top. This recognition action will be done several times by the user during the life of the app.
The user chooses to launch the recognition by clicking on a button (or otherwise but he knows that the recogntion will start). So no notification is needed.
The thing is he doesn't choose the way to do the recogniton. It is why, as you said, I implement an adapter.
The adapter chooses between :
Camera mobile or external device. The first is an activity coming from the Zxing library. The second one is a service that manages the external device. This service provides an interface to get back result.
One more thing, I need that my whole implementation (adapter and co) can be re-used by other apps that will also need to do recognition.
So my thought was to implement a service as an adapter to answer my two conditions (make transparent the choice for the user - and make the recognition available for other apps).
I hope you understand my problematic.
Given your architecture, your MyOwnService must act as an API adapter : it should provide a unified scanning API and address each external service specificities transparently.
Your expected behaviour is not clear enough to provide a solution that suits your needs but here are a few remarks that can be of some help.
Passive scanning:
Even if there are some workarounds : no activity should be launched from a service (not directly). Never. Bad. Services are background stuff, the most they will be permitted is to hint users with Notifications (this is point 2 of Justin excellent answer).
As a consequence there's nothing as a 'popup Activities' (and that's good!). If you need to continuously scan for barcodes, even when your activity is not run, then the only way to warn users is by using status bar notification.
Active scanning:
Inside your own activity you can bind to your wrapper service and make it start scanning for codebars. When it finds one it has to message your activity. Your Activity message handler has complete access to the UI to inform the user of your findings.
You selected Active Scanning in your edit, your problem is therefore to find a way for your service to actively notify your main application (the one that started the active scanning) that a new item has been scanned successfully.
You do NOT do this by starting a new activity (remember: this is bad) but you can bind to a service and/or use Messages between the wrapper service and the application.
I advice you take the time to read (and more time to comprehend) this android developer article on BoundServices and especially the part about Messengers.
A full example of Two Way Messaging between a Service and an Activity can be found in the following android examples : Service & Activity
Warning: designing robust, full blown AIDL-based services is a tough job.
Two ways you could solve this problem.
1) Have MyOwnService do a callback into MainActivity telling it to launch your ScanActivity.
- This is a better approach if MyOwnService's task is only going to be running while MainActivity is running and if the user would expect the ScanActivity to come up automatically.
2) Have MyOwnService create a notification that will let the user access the ScanActivity.
- This is a better approach if MyOwnService's task might be running longer than the life span of MainActivity. That way, you can let the user know, unobstrusively, that they might want to access the ScanActivity.
So finally I changed my architecture.
I make the choice to delete myOwnService and to create an intermediate activity that will be my API Adaptater.
This activity will have a dialog.theme to look like a dialog box indicating that a recognition is under execution.
If the recognition uses the external device this activity will stay at the foreground otherwise the camera activity will start (Being managed by the intermediate activity).
Thank to that I can manage my result from the intermediate activity and do not have an android strange architecture, keeping my business code for the recognition outside my main app.
Service was not the good choice.
Thanks a lot for you help and your time.

Categories

Resources