Monday, August 19, 2013

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

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