Skip to content
This repository has been archived by the owner on Mar 16, 2021. It is now read-only.

Support use across multiple processess, how to use it? #28

Closed
kamilwlf opened this issue Jun 3, 2015 · 2 comments
Closed

Support use across multiple processess, how to use it? #28

kamilwlf opened this issue Jun 3, 2015 · 2 comments

Comments

@kamilwlf
Copy link

kamilwlf commented Jun 3, 2015

Support use across multiple processess

I'm trying to understand how can I take advantage of it . Can you give a practical example ?

Is it simply writes data asynchronous?

what will be happen when the app is killed before the data has been written to disk?
Is it true 'commit' semantics?

Topics that do not fully understand:

Tray solves this problem with a ContentProvider based storage.

What are the benefits it gives to us? Why we want use ContentProvider? Whether it's sharing of resources between different applications ?

Works multiprocess

So I can save several values ​​in parallel?

automatically saves metadata for each entry (created, last updated, ...)

I do not understand? automatically saves metadata?

At first, it was the simpst way to use IPC with Binder to solve the multiprocess problem. Using the ContentProvider with a database turned out to be very handy when it comes to save metadata. We thought about replacing the database with the real SharedPreferences to boost the performance (the SharedPreferences do not access the disk for every read/write action which causes the multiprocess problem btw) but the metadata seemed to be more valuable to us.

Why we want use ContentProvider? Whether it's sharing of resources between different applications ?

@passsy
Copy link
Contributor

passsy commented Jun 3, 2015

IPC for multiprocess support

To share data between two processes you need inter-process communication (IPC).

A common android example for this are SyncAdapters which run on different processes than your UI. When you want to trigger an action in the UI from your SyncAdapter you can't simply call a function of your activity you need to use IPC. When you use the SharedPreferences in the SyncAdapter you are able to save the data. But the UI (in a different process) uses a different SharedPreferences object and does not receive a data change. Even worse, if you read the value written in the SyncAdapter from the UI process you get the old value for some seconds. (issue on StackOverflow)

Implementing Binder for IPC is hard and low level. But ContentProviders do IPC out of the box. That's why a ContentProvider is used to support multiple processes.

Why a database

A ContentProvider doesn't mean the data is written to a database. It's just a interface which supports CRUD operations. And those operations are process save. Yes, Tray is using a sqlite database under the hood but if would be possible to swap out this implementation and save the data to any other persistence framework. This works because the ContentProvider would use the same persistence Object for all operations. But the multi process support would only be guaranteed when you access the data with Tray and the ContentProvider and not directly with the other persistence frameworks.

So ContentProviders makes CRUD operations multi process save.

The Sqlite database is used to store the data. It's no just a simple key value store (like the shared preferences) because you can get additional informations for every key value pair saved to Tray automatically. You can get informations when the data was saved first or when the data was last updated. (see here).

ContentProvider facts

  • The ContentProvider used is only accessible from your Application.
  • You can override this permission in your manifest to make it public accessible.
  • If you want you can access the data in the ContentProvider directly with getContext().getContentResolver().insert(uri, values);. This means Tray is just a high level abstraction to access the data in the ContentProvider.

Tray is not async

Tray doesn't support asynchronous operations. Everything runs synchronous. A mPrefs.put("key", "data"); immediately writes the data into the database. If this function returns the data is saved to disk.

It's up to the developer where to save the data, inside the UI Thread or in a worker thread. In my cases this was never a problem because I was writing data in a non-UI process where I didn't have to care about frames.

I hope I could help you understand this lib 😄!

@kamilwlf
Copy link
Author

kamilwlf commented Jun 3, 2015

so now everything is clear.

I propose to describe(copy your text) it on the main page or in the documentation

@chechuangfeng
Copy link

I have a question,when a call mPrefs.get("key") on the ui thread, and it is synchronous, will it block the UI thread when the data is so big?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

3 participants