GCX-HCI / tray

a SharedPreferences replacement for Android with multiprocess support
Apache License 2.0
2.29k stars 272 forks source link

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

Closed kamilwlf closed 9 years ago

kamilwlf commented 9 years ago

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 commented 9 years ago

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

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 :smile:!

kamilwlf commented 9 years ago

so now everything is clear.

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

chechuangfeng commented 9 years ago

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?