Making Asynchronous Service Calls in Android - android

I am trying to make asynchronous service-call in my android app using AsyncTask Class, but for each and every service call in my activity i need to have a subclass in my Application which Extends AsyncTask. Can anyone Suggest me a better way of doing this???
In My Scenario Service Calls have different return-type,then i need to return an object for all service calls and typecast it according, Is there any better way of doing this ???

Is it a service you wrote? If so, you could make the service itself asynchronous so that you can make calls on it that return instantaneously and later get notified via a callback. That would remove the need for the AsyncTasks on your Activity.
If you can't change the Service, one thing you can do is have a background worker thread that's responsible for interacting with the Service, and you post messages to it from the main thread using a Handler. The worker thread uses another Handler to deliver the results back to the UI thread once each work item is finished.
See: http://developer.android.com/reference/android/os/Handler.html

"AsyncTask must be subclassed to be used." sez the droid.

Don't declare the AsyncTask as an inner class of your activity. Declare this class once in it's own scope, and you can use it from anywhere. As far as the data to pass in and out, you can make the first parameter a String or Uri and pass in the request data, and you can use an internal listener object in the AsyncTask that can be set by the activity to receive a call back when onPostExecute fires.
EDIT
I made a gist to demonstrate the simplest version of this. Using the example AsyncTask-derived class, you can reuse this one class throughout your entire app and pass it all of your endpoints and receive the result inside your activities (or anywhere else you need to make your service calls). If you need to make this more extensive, you can just change the input object from a String to some more complex data structure containing anything you need to pass to your service call (post params, http method, etc) and you can change the signature of the OnPostExecuteListener interface if you want to return structured data and not just the raw result
https://gist.github.com/80c59fb70e195ca142bb

Related

Android studio AsyncTask

I am using sockets and im getting data continuously in background using Asynctask.
I send this data to onProgressUpdate() with publishProgress()and I would like to know if there is a way to get the data from function onProgressUpdate() or send it to another class, because where I do need to use this data is in another class. At least, is this possible?
I have a .java, in this .java I have 2 public classes:
First one is a class where I use this Asynctask in background to get socket info.
In the second public class I use OpenGL and I need to use that data.
Thank you
Sure it's possible. You define the type of the array passed between doInBackground() and onProgressUpdate(). You can just publish the progress and consume it that way.
new AsyncTask<...,MyDataObject,...>() {...}.execute();
Alternatively, you can create a publish-subscribe interface between the thread running dIB() and whatever thread is consuming it.
Not that AsyncTask isn't intended to be used for long-running operations. It's meant to be a relatively quick one-shot. You'll need to consider running your task on a dedicated executor so as not to block the one serial executor that's used by default for all other instances of AsyncTask. E.g.,
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
Yo can do this with publishProgress() method and you can call this method from doInBackground() and this method can be called at any time when you need to get your data.
Then get data what you want from params and store it in public variable of Asynctask and access it from another class.
This may be work.

How to have one AsyncTask for all my db calls

I am looking for the right way of designing my app here.
I have 5 activities and each one calls a separate DB method (update, insert, delete ..etc).
I was wondering, instead of creating 5 asynctask classes, each is a private class belonging to the activity to be called from, is there way I can create one asynctask class so I instantiate its object in all the activities?
In C++, you can pass "an entire method" to be executed so Ican create an assign task and pass a method to it to be executed, but I am not sure I can do that in Java. Or what would be the best practice in your mind?
Thank you
Check the Runnable class.
A Runnable represents a task that can be executed. You need to implement it's run() You can pass an instance of Runnable to your AsyncTask and execute it in it's doInBackground(...) method.
There might be a better way to do this, but this is the only thing that is comming to my mind right now.
I'm not sure if this would fit your bill but I would recommend creating an IntentService, that would automatically and asynchronously queue up your Database/Content-Provider read and writes.
You can write separate read, write and update methods that will be handled in the onHandleIntent method of the IntentService. The Intent service insures that
the database/CP access is done asynchronously
successive database/CP access requests are automatically queued and handled
the Service is stopped/started automatically, no need to manage the lifecycle
the database/CP read/write is done even if the app goes into the background
For ListView/Adapter access, consider using loaders

Posting on the UI thread from a singleton manager class

I have a singleton manager class that is called from Activities (UI thread), then it operates on a different thread (Network) and in the it end should call a callback method in the calling Activity.
I was wondering what is the best way to call the callback methods on the UI thread.
I an familiar with the options (see http://android-developers.blogspot.co.il/2009/05/painless-threading.html)
So I was thinking of two options:
the first:
The calling Activities will implement an Interface with a getActivity() method. that method will be used to call Activity.runOnUiThread(Runnable).
the second:
MainApplication, which inits the manager singleton, will pass a Handler instance that belongs to the UI thread.
What is the better option?
I'm also happy to hear any other suggestions
Regardless of what option you choose, you have to keep in mind that the activities have a certain lifecycle, and unlike your singleton class can be finished or moved to the background. In light of this, you should consider again whether singleton is really the best choice here: if it needs to interact with an activity, maybe the activity should manage its lifecycle. If it doesn't depend on any particular activity, you might want to make it a service and send out broadcasts to notify about progress, etc.
What exactly are you trying to do?

Pattern for reusing Android AsnycTask over several Activities?

I have several Activity subclasses in my project, each calling a SOAP based web service, processing and displaying the results. The SOAP serialization, the call handling and the parsing of result into various POJO objects is encapsulated in the MyWebService class. This class executes the actual web service call(s) via an AsyncTask.
For being able to pass back the results to the calling Activity subclass, I figured I enforce that all these activities should implement a WebServiceResultProcessor interface, defining a single function (processWebServiceResults) acting as a callback for the AsyncTask, called from onPostExecute.
I also want to display a ProgressDialog during the web service call. And here comes my question. For being able to display the ProgressDialog (either from MyWebService or it's AsyncTask), I need to pass a reference to the caller Activity's Context. And for being able to execute the callback function from the AsyncTask, I also need to pass the same object reference, but this time as a WebServiceResultProcessor. This seems to me a code smell, passing the same object twice, but can't see any way around that. Instead of interfacing, I could create a new base class, extending the Activity class and enforce inheritance from the extension class, but that would mean I'd exclude ListActivity and the likes from using this MyWebService class.
Is there a better way to do this?
+1, a nice question!
This is not a direct answer on your question. However let me say I think AsyncTask is not a right choice for such stuff. I think so because in this case AsyncTask holds a reference to an Activity (via ProgressDialog instance or the callbacks to be called from onPostExecute()).
Just imagine: in Android the OS may kill the Activity before AsyncTask executes its doInBackground(). This is, of course, some sort of a corner case, but it isn't impossible. Consider a scenario: user gets an incoming call, your activity becomes invisible, the OS needs some more RAM and thus it decides to kill your activity. A memory leak case, at least.
I don't know why Google literally hides the info on how UI should be properly separated from background tasks. Yes, they say "use a Service". But it is not a trivial undertaking. It's a pity Google provides nice guides to almost every development topic, but not on this one. Nevertheless I can suggest to check the "Google I/O 2010 - Android REST client applications" presentation for inspiration. Looks like they gave a key on how such things should be done in Android.
You may have a look into this blog article (part 1 and part 2), which implements a web service with AsyncTaskLoader and the same web service with a Service component. Furthermore it shows the differences between both approaches and there are also interesting comments to the article.
Despite Arhimed's warning, I ended up using AsyncTask, as it still fits my purposes. I just make sure that all Activities calling web services, upon their onDestroy(), send a cancel() to the invoked AsyncTask. The AsyncTask implementation itself gracefully handles the cancel request by checking isCancelled() everywhere where necessary.
As for the original question, I must have had a lapse - the solution is really simple. I pass the Activity subclass instance as an Object to the AsyncTask, and cast it to either Context or to WebServiceResultProcessor, as necessary. Fragments showing how it works:
if (callerActivity instanceof Context) {
ProgressDialog dialog = new ProgressDialog((Context)callerActivity);
}
...
if (callerActivity instanceof WebServiceResultProcessor) {
((WebServiceResultProcessor)callerActivity).processWebServiceResults(soapObject);
}

Activity with backgroundthread, not innerclass, communication

Hey all, this will contain a few questions since I don't seem to really get it.
I have 1 class, the activity. which should display informations.
Then I have a background thread, extends runnable, which keeps getting new data (there for I didn't use AsyncTask, I could use it as a service, but since I hold a some critical resources in it, I would like not have it released when exiting the activity thread)
But I am in great doubt how to communicate between these 2.
First I thought of Intent, but these seem to be used mostly for launching other activities, or alike, and I need something permanent, since data will be in a steady flow.
Then I found out handler, but this doesn't seem to work when my thread is not an innerclass, so I'm thinking about either going back to the old Java observer pattern, if it's not possible to somehow pass the handler to the outerclass.
Any thoughts would be greatly appreciated
Sincerely
Anders Metnik
There is a mechanism for your case - it is called handlers. Read more here.
As for having thread as inner class:
Create your thread as a separate class, add a constructor with a handler parameter and pass it from your activity.
Thread is not suppose to live outside Creator Activity Context, especially you want to preserve it out of Activity, better use Service (and manage the thread) to hold those data.
Intent is the best in terms of communicating between contexts. I think one of the scenario you can adopt is like this:
Application-class: holds those 'permanent' data you mentioned
Service-class: Work (background) and send out "intents" to signal the update state of the operations
Activity-class: Intent Receiver. Whenever intent signal received, grab the necessary data from the Application-class.

Categories

Resources