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 [email protected]
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to