Skip to content


Subversion checkout URL

You can clone with
Download ZIP
100755 178 lines (133 sloc) 8.234 kB
c27720a @commonsguy Initial import
1 CWAC Prefs: For When Regular Preferences Just Aren't Enough
2 ===========================================================
4 `SharedPreferences` are persisted in an XML file, in the internal storage
5 of your app. In many cases, this is perfectly fine. In other cases,
6 though, you might want to store those preferences in some other container.
7 This project provides another implementation of the `SharedPreferences`
8 interface, one where you can supply a strategy object to define how
9 the values should be loaded and persisted. Built-in strategies support
10 storing the values in SQLite, or encrypted in SQLCipher for Android.
923d9b2 @commonsguy Update README.markdown
12 This is [available as a JAR file](
c27720a @commonsguy Initial import
13 Note that if you wish to use the JAR *and* use the encrypted
14 preferences, you will also need a compatible edition of SQLCipher for Android.
16 The project itself is set up as an Android library project,
b52c0cc @commonsguy updated for asset issue
17 in case you wish to use the source code in that fashion. However, you will still
18 need to make a copy of the contents of the library's `assets/` directory in your
19 project, as assets are not automatically shared from a library project to its
20 host.
c27720a @commonsguy Initial import
22 Usage
23 -----
24 Most of your usage of the `CWSharedPreferences` class (in `com.commonsware.cwac.prefs`)
25 will be the same as how you would use `SharedPreferences`. `SharedPreferences` is
26 an interface; `CWSharedPreferences` implements that interface. Hence, you still use
27 methods like `getInt()` to retrieve preference values, `edit()` to get an `Editor`
28 with setters like `putInt()`, and so on.
30 What differs is how you get the `CWSharedPreferences` object in the first place. You
31 will not get one from the standard `PreferenceManager` or via some method on `Context`.
32 Rather, you will use a `getInstance()` method on the `CWSharedPreferences` class, supplying
33 a strategy object to use if the `CWSharedPreferences` object does not yet exist. As with
34 `SharedPreferences`, `CWSharedPreferences` are held onto in a static data member and will
35 live for the life of your process, treated as a singleton on a per-name basis.
37 ### Defining and Using a Strategy
39 The static `getInstance()` method on `CWSharedPreferences`, to give you a `CWSharedPreferences`
40 object, takes a `CWSharedPreferences.StorageStrategy` object as a parameter. This interface
41 defines where and how the preference values are loaded and stored.
43 There are two standard implementations of `StorageStrategy`:
45 - `SQLiteStrategy`, which stores its data in a SQLite database
46 - `SQLCipherStrategy`, which stores its data in a SQLCipher for Android encrypted database
48 The constructor for `SQLiteStrategy` takes three parameters:
50 - a `Context` object for use with an internal `SQLiteOpenHelper` implementation
51 - a string representing the name of the database file to use (also serves as a unique key for
52 the static cache of `CWSharedPreferences` instances)
53 - a `LoadPolicy`, described in greater detail below
55 The constructor for `SQLCipherStrategy` takes those parameters, plus the password for the
56 database. This password will be used to encrypt the database if this is no existing database,
57 plus it is used to decrypt the database as needed over time.
59 ### Load Policies
61 The `LoadPolicy` indicates what should happen when the `CWSharedPreferences` is created
62 and needs to load its data. There are three possible `LoadPolicy` enum values:
64 - `SYNC` means that the `CWSharedPreferences` will load its in-memory cache of the preference
65 values on the current thread. Use this if you are using your own background thread to initialize the
66 `CWSharedPreferences` instance and do not need `CWSharedPreferences` to fork
67 its own thread for this purpose.
69 - `ASYNC_BLOCK` is the same basic behavior you see with the stock implementation
70 of `SharedPreferences`: the data is loaded in a background thread, but your
71 attempt to read that data blocks until the load is complete.
73 - `ASYNC_EXCEPTION` will throw a `RuntimeException` if you attempt to read
74 from a `CWSharedPreferences` where the load has not yet completed.
76 `SYNC` is generally the best answer, as you are assured that you will not block
77 the main application thread. `ASYNC_BLOCK` *could* block the main application
78 thread if you try using the preferences right away and they have not been loaded
79 yet.
81 So, for example, you could create a `SQLiteStrategy` object via:
83 new SQLiteStrategy(getContext(), NAME, LoadPolicy.SYNC);
85 (assuming a static data member named `NAME` that is the database name, and
86 assuming the existence of some `getContext()` method to return a `Context`)
88 Then, you could retrieve a `CWSharedPreferences` via:
90 CWSharedPreferences.getInstance(new SQLiteStrategy(getContext(), NAME, LoadPolicy.SYNC));
92 ### Limitations
94 Due to some [unfortunate limitations](
95 in the way `PreferenceFragment` and `PreferenceActivity` work, there is no known
96 simple way to use `CWSharedPreferences` with these classes.
98 Dependencies
99 ------------
100 To use the project with `SQLCipherStrategy`, or to build the project
101 from source (including using it as an Android library project), you
102 will need to download and install SQLCipher for Android. The library
103 project already has a compatible edition, so if you clone the repo and
104 use the library project *in situ*, you should be OK. If you wish to
105 use the JAR instead, visit [the SQLCipher for Android](
106 Web site to learn more about how to add it to your project.
108 Other than that, there are no dependencies for the main project.
109 Notably, if you are using the JAR and not using `SQLCipherStrategy`,
110 you should not need SQLCipher for Android.
112 Version
113 -------
cd0cea5 @commonsguy updated for v0.0.2
114 This is version v0.0.2 of this module, meaning that this is a proof
c27720a @commonsguy Initial import
115 of concept, seeking input from interested parties.
117 Demo
118 ----
119 Normally, CWAC projects have a `demo/` subproject. This one does not.
120 In part, that is due to the UI limitations mentioned above.
122 It does, however, have a `tests/` sub-project that implements a JUnit
123 test suite for exercising basic aspects of the API. Note, though, that
124 these tests are "white box", insofar as the tests live in the same
125 package as `CWSharedPreferences` and access package-private methods.
127 License
128 -------
129 The code in this project is licensed under the Apache
130 Software License 2.0, per the terms of the included LICENSE
131 file.
133 Getting Help
134 ------------
135 Do not ask for help via Twitter.
137 And, for those of you who skipped over that sentence: do not ask for help on Twitter. Anyone who thinks that
138 developer support can be handled in 140-character chunks should not be attempting to use a CWAC component.
140 Now, that being said, the rest of your help will be for bugs or questions.
142 ### Bugs
144 If you are experiencing some sort of problem using this component, where you are fairly certain the component
145 itself is at fault, please submit a pull request
146 for a new test case to be added to the `tests/` project that demonstrates the problem. Or, create
147 a sample project that demonstrates the problem, post the source code to
148 that project somewhere (e.g., a public GitHub repo), and file an
149 [issue](, pointing to your project and providing
150 instructions on how to reproduce the problem.
152 Do not file an issue if you cannot reproduce the problem, or with only partial source code that may or may
153 not be related to the problem.
155 ### Feature Requests and Non-Bug Issues
157 If you see likely flaws just by looking at the code, or you see places where we
158 would really need additional stuff for this to be useful, please file an
159 [issue](
161 ### Other Questions
163 If you have questions regarding the use of this code, please post a question
164 on [StackOverflow]( tagged with `commonsware` and `android`. Be sure to indicate
165 what CWAC module you are having issues with, and be sure to include *relevant* source code
166 and stack traces if you are encountering crashes.
168 Release Notes
169 -------------
0eeb5bf @commonsguy updated for v0.0.3
170 * v0.0.3: bug fixes
cd0cea5 @commonsguy updated for v0.0.2
171 * v0.0.2: minor issue fixes
c27720a @commonsguy Initial import
172 * v0.0.1: Initial import
174 Who Made This?
175 --------------
176 <a href="">![CommonsWare](</a>
Something went wrong with that request. Please try again.