Wednesday, August 21, 2013

[android-developers] Re: How do I call a service, to retrieve data, from a content provider?

You're comparing apples to oranges... The point of a service is to manage "requests", not to "background" anything since obviously a Service does not actually background anything (except for IntentService).
It's more fit for something that doesn't pass big amounts back to the requester, at least not directly.

And yes, services get's killed on low memory as well, but remember that actually having a service, puts you higher up in the priority (especially a foreground one, which is only second in priority to the active application), so even that is an added benefit of using services instead of trying to control everything with just ASyncTasks.

And no, services still make a lot of sense, which has nothing to do with them being "old"... i think you're not getting what they are and what they are for completely... better read the documentation about them, maybe some in depth tutorials showing how to use them properly to fully grasp why they are needed.

P.S - I use services to call webservices myself :) they are perfect when you want to design a system that updates/syncs information in the background (where background means - unrelated to the current visible UI, not just as a background thread).. 


On Tuesday, August 20, 2013 7:18:15 PM UTC+3, user123 wrote:
Thanks. I also suspected that I'm overcomplicating it :)

The thing is, basically, that I saw this approach using a service in a Google IO talk about REST services (from 2010). Also, some code I worked with recently also used a service (but without content provider or database access). I thought this must have a reason, otherwise Loader or AsyncTask looks far more handy. Or in my case just calling it synchronously in the same thread where I'm accessing the content provider.

Recently I also read that the service is killed similarly to the activities when e.g. the system is low of memory. So it seems there's also not a higher reliability. In other words, I have no idea why this talk showed the use of services so frequently. Maybe because it's old (although at that time there were at least threads, and that's still more use friendly to call webservices than a service). 

The code I received, were there were also services, I guess this company also was inspired by the same talk.

Still I'm curious if there's a real reason to use a service only to call a webservice? Maybe somebody sees a point which I'm missing.





Am Dienstag, 20. August 2013 08:42:36 UTC+2 schrieb Piren:
Because I want that once started, it will receive and process the response, even if the user exits the app / the system kills it, etc. 
That has nothing to do with Services though... any ASyncTask you start or any Thread you start will continue even if you exit the app. Services die just like any other component once you Kill the app (with the exception of "sliding" an app from the Recents list and the service being a Foreground service).

You're over complicating things... process the information on the same component that retrieves it or at least store it for whatever comes next. Also, if the web call needs to download a lot of information, it's best to implement a chunking mechanism and support being able to "resume download", killing your app will have less of an impact.

On Monday, August 19, 2013 10:27:29 PM UTC+3, user123 wrote:
I'm trying to implement a pattern of accessing data source, independently if it's local or remote, using a content provider.

So, inside the content provider, for example in the query method:

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {...}

I want to, check if data is stored locally, if not, then call the webservice, on response save and return it. Typical request process with a local cache.

Now to get the data from the webservice, I wanted to use a service. Because I want that once started, it will receive and process the response, even if the user exits the app / the system kills it, etc. 

Note: I don't need to use anything synchronous here, since I'm already running the query to the content provider asynchronouly (AsyncQueryHandler). So I think I have to use Service instead of e.g. IntentService.

The idea with the service is to have a method to call the webservice:

public WebserviceResponse callWebservice(params) {...}

And in ContentProvider.query(): 

WebserviceResponse response = myService.callWebservice(params);


But the problem is that I can't find how to ensure that the service is already bound before the first query. If I bind it in ContentProvider.onCreate:

@Override
public boolean onCreate() {
    final Context context = getContext();
    dbHelper = new DatabaseHelper(context);

    context.bindService(new Intent(context, MyService.class), mConnection, Context.BIND_AUTO_CREATE);
    return true;
}

Where mConnection is:


private ServiceConnection mConnection = new ServiceConnection() {

   public void onServiceConnected(ComponentName className, IBinder binder) {
        myService = ((MyService.MyBinder) binder).getService();
   }

   public void onServiceDisconnected(ComponentName className) {
        myService = null;
    }
};

And I do a query using this content provider in my activity's onCreate(), the service is not bound yet and I get an exception when I try to use it.

A way around I can think of, is to call the webservice directly - without a service - from the content provider. This will be synchronous and I can process the response without problems there. But it has mentioned disadvantage that the call can be interrupted and the data not processed. It's not the end of the world - the next time the user opens the app, the webservice would be called again. But I still would like to not have it that way.

A second possibility I can think of, is to invert this logic and do the access to the content provider in a (asynchronous) service. But here I have a different problem, which is that, afair, the async service (IntentService) communicates with the caller though with IPC and this is not supposed to pass large amounts of data. So I would have again to wrap this in some other logic which after service is finished checks a flag and retrieves data, this time directly from the content provider. This would also mean to start a second async query.

I already came up with an architecture that works, but it's quite complex. It:

1. Does async query to the content provider
2. If there's no data, starts an IntentService to get it from remote.
3. After the service finishes it returns a flag, and then, does again async query to get the data which was saved by the webservice.

I would like to simplify it, that's why I'm asking this. 

So is there any way that I can use the service in the content provider, or any other approach, or advice you would recommend?







--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
---
You received this message because you are subscribed to the Google Groups "Android Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-developers+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home


Real Estate