Blocking/Synchronous function call in AIDL - android

I am working on a android service, this service provided a AIDL interface for applications, Now application calls function GetData() using AIDL interface, this function is implemented in Service , it does some network operation, connect to server and fetch some data, this network transaction happen in background thread, Problem is that I want function GetData() should NOT return until network operation is complete, result comes from server and I want to return it into GetData(), GetData function returns immediately and network operation in background thread keep on running in parallel, how to avoid this, cannot call network operation also in main thread. I read about countDownlatch, is it only possible solution?
Service Main Thread
GetData
GetDataFromServer-----------> in Background thread
/*this is problem */ GetData returns; |
|
|
communication in progress
|
|
|
/*I want GetData should return here <-------------------transaction complete

Create some interface and implement that interface in your class and pass the interface object to that particular service after response came from the network pass the data to that interface object.
i think this help you.

you can call startService from AsyncTask.I can have the same problem in my nearest place application that need data from google map.enter code here
protected void getLocationAndUpdatePlaces(boolean updateWhenLocationChanges) {
// This isn't directly affecting the UI, so put it on a worker thread.
AsyncTask<Void, Void, Void> findLastLocationTask = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
// Find the last known location, specifying a required accuracy of within the min distance between updates
// and a required latency of the minimum time required between updates.
// start a service that require data from web.
}
};
findLastLocationTask.execute();
`

Related

How to start a clientTask from within a ServerTask in Android?

I have a client-server app, where each app has both client-server functionalities.
The client in one app sends a number, to which the server side on the second app has to reply. To reply, I need to start a client Task to do it. But I get the error "Method executeOnExecutor must be called from the main thread, currently inferred thread is worker".
I cannot show the exact code, so I am posting some psuedo code for better explanation :
private class ServerTask extends AsyncTask<ServerSocket, String, Void> {
#Override
protected Void doInBackground(ServerSocket... sockets) {
...receive from client.. do processing. need to reply
new ClientTaskName.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR,message);
}
}
private class ClientTaskName extends AsyncTask<Message, Void, Void> {
#Override
protected Void doInBackground(Message... params) {
//... do something...
return null;
}
}
If I am not allowed to create a clientTask from within the serverTask, what are my options ?
EDIT:
I am adding a basic overall process flow:
Process A send msg1 to process B.
Process B receives it in ServerTask, replies to it
Process A receives the reply, decides some additional parameters based on the reply, sends ACK with the decided parameter.
Process B receives ACK and configures its own future messages with received parameter.
This requires that the ServerTask handle two types of messages in its doInBackground function, one where it expects only ACK, and one where it will reply to the received message.
The steps 1-4 will run arbitrary number of times.
SDK used : API 19
Use threads instead of AsyncTasks.
That is how it is normally done.

retrofit for android - how to do sequential network calls

in my android app i have 3 network calls and they are dependent on the call before it. So 1 must finish, then 2 can go and finally 3 gets run with the data from the previous ones. So i need the network calls to run sequentially is the goal. after one call is finished it will have data passed to the next call, etc. I dont want to use rxJava. Is there a way with retrofit to make this happen ? My project is already using retrofit thus i want to continue using it ? I've tried playing around with asynchTask but its not clean and since im using retrofit i thought i would ask.
If you're using Retrofit with the asynchronous Callbacks then for the first network call you can pass in the generated interface which represents the web service that you're interacting with. In the success method you can then use the instance of the generated interface to make a second network call, using the data which came back in success under the parametrised type T, and so on for the third call inside a second callback. For example:
class FirstCallback implements Callback<First> {
private Api api;
public FirstCallback(Api api) {
this.api = api;
}
void success(First data, Response response) {
api.secondCall(data, new SecondCallback(api))
}
}
// somewhere else in your code
api.firstCall(new FirstCallback(api));
This is a quick solution using chaining with the asynchronous calls. This would most likely look more sequential and easier to read inside of an AsyncTask using the synchronous calls, which would return the type T directly. For example:
class MyTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
First first = api.firstCall();
Second second = api.secondCall(first);
// ...and so on until you return the final result
}
}

Using AsyncTask to update UI

I have problem when implementing AsyncTask. I have to rotate my phone in order to get a recent information. Below is my class:
GamerObject gamer;
….
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ip = "134.188.204.155";
// Set the name of the gamer
gamername = (TextView) findViewById(R.id.gamer_name);
// Set the gamerstatus:
gamerstatus = (TextView) findViewById(R.id.tvgamer_status_msg);
// set the job status
jobstatus = (TextView) findViewById(R.id.tvJob_status_msg);
new Operation().execute();
}
private class Operation extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
gamer= new GamerObject(ip);
gamer.UpdateAllData();
}
#Override
protected void onPostExecute(Void result) {
updateUI();
}
}
private void updateUI() {
gamer.updateAllData();
// Set the name of the gamer
TextView gamername = (TextView) findViewById(R.id.gamer_name );
gamername.setText(gamer.gamername);
gamername = gamer.gamername ;
// Set the gamer status:
…
// set the job status
…
}
Before I was using a Intent for Refresh the Interface, but now I want to try using AsyncTask so that it can compatible with Android version 4. Anybody knows how to get the information updated without rotating the phone ?
EDIT:
If I'm not wrong, Why my UI didn't refresh if there is new value, it is because new Operation().execute(); only use once in onCreate. AsyncTask will be executed if onCreate has been called, which means every time I rotate my phone, it will go to onCreate . Anybody knows how to keep the AsyncTask executed?
AsyncTask will only be executed once, so whenever system calls onCreate on your activity dueto some lifecycle event, asyncTask will be executed.
One, simple but naive approach, would be to create a new Thread and use Handler to update your UI. Some more information can be found eg. here and of course in Android doc.
Better approach, but more complicated would be to use Loader and LoaderCallback along with ContentProvider as #metter mentioned. This will require implementing you own ContentProvider and force you to add more "abstraction layers" to your app but will allow to separate network base code and ui code.
So this is as always tough decision to make either use "simple" but ugle solution with threads or "harder" but elegant solution with ContentProvier
I want to get the inofrmation updated automatically without have to rotating the phone.
Doing that requires some more work. Unfortunately, we can't see what your Async task actually does. If it is reading data from a database and you wan't your UI to be informed about any changes to the database, then your content resolver could call it's notifyChange and your Activity would listen to these changes and then call the async task again. For that, you would use a Content Observer. However, if your task is downloading data from the web, then there are two methods to get informed if the data online changed. One is called polling and means that you periodically connect and check the server. You should never do that on a mobile device due to limitations in battery, performance and data traffic. The other is called pushing and requires you to set up some infrastructure.
I hope that helps you.

Design-Pattern for a Service like Architecture

What Design-Pattern would be intelligent in which following Components(simplified) exists:
3 Components
- GUI
- Data fetcher
- Database
I have no Access to the Server in the Internet, its just a Data-Source. The Data which lays in the Internet is always the newer one, the local-Database is just a copy(cache) of the one in the Internet. The GUI can request and update of the local cache, the Service-like-component fetches then asynchronously the newest data, which could take awhile.
The GUI shows only Data from the local Database, which he can fetch synchronously.
So my Question is, what classes would you use for the maybe longterm running Service with Progressbar capabilities ? Are there better Designs for this kind of "problem"? Are there better practices?
On the Service Like Component:
An interface (method) to kick off the update process. Typically this service would return a jobId to indicate a job that is being processed in the background
Another interface (method) to get the status based on a particular jobId. The implementation of this service could return a status, percentCompleted or any other relevant info that will tell the caller the current status of the update process. The implementation of this method needs to be able to report an incremental progress (such as reporting the incremental store in the local storage) in order to make an accurate progress bar, otherwise the best the UI could do is show the spinning progress bar.
Note that if such incremental reporting is not possible to implement then the Update process should probably use a typical AsyncTask usage which execute update in the background and report to the user when it is finished. If this operation might take a while, you could implement the completion of the update via Android notification bar or push notification.
Assuming you have the interface to get the progress of the update, you could utilize the AsyncTask onProgressUpdate to report the progress of the update. The method is specifically designed for that.
Your steps are roughly as follow:
Execute the interface to update via one AsyncTask. Since your update is happening asynchronously, this particular task should return fairly quickly with a status reporting whether the execution is running successfully or fail because some exception along with the jobId that it is currently executing
Launch another AsyncTask that is pinging the status of the update and report the progress via onProgressUpdate. The AsyncTask roughly looks like
public class GetUpdateStatusAsyncTask extends AsyncTask {
protected Integer doInBackground(Integer... param) {
// this is the jobId that you get from the previous AsyncTask that you use to kick off the
// the update process
int jobId = param[0];
double percentCompleted = fetchStatus(jobId);
while(percentCompleted != 100.00) {
publishProgress(percentCompleted);
}
// return status code
return 1;
}
protected void onProgressUpdate(Double... progress) {
// set the progressBar here
}
protected void onPostExecute(Long result) {
// done, handle status code
}
private double fetchStatus(int jobId) {
double percentCompleted = 0.0;
// call interface to get the update based on the jobId
// return percentCompleted status or make a more complex object if you need
// more detail info
return percentCompleted;
}
}

Threads and Events - what's the best way?

I have a class which reads the calllog. This could last some minutes. So I have to use a thread if I don't want to block the gui thread.
In C# I start a thread, notify the gui thread with a event when the data is ready and give the data to the gui within the event.
But how should I do it with android? What I read so far told me that's the best to use AsyncTask with android. I use it in this way (Pseudo code):
class MyClass{
private myClassVariable;
private coid startTask(){
GetDataTask data = new GetDataTask();
data.execute(varibale);
}
private void displayData{
doAnythingUsefullHere;
}
class GetDataTask extends AsyncTask<variables>{
protected variable doInBackground(variable){
return = CallLog.getData();
}
protected void onPostExecute(variable){
myclassVariable = variable;
displayData;
}
}
}
Works fine so far, but I can't cancel the thread in this way. I could cancel the task, but I have to check within the data collect loop of the calllog class if the onCancelled is called but this function is only known in the class GetDataTask and not in CallLog.
Is there a way to use AsyncTask and make "outside" classes cancelable? Or have I switch to Threads and events? What's the best way in this situation?
Could this be what you are looking for: Ideal way to cancel an executing AsyncTask ?

Categories

Resources