Giter VIP home page Giter VIP logo

paper's Introduction

Paper

Android Arsenal Build Status

Paper's aim is to provide a simple yet fast object storage option for Android. It allows to use Java/Kotlin classes as is: without annotations, factory methods, mandatory class extensions etc. Moreover adding or removing fields to data classes is no longer a pain – all data structure changes are handled automatically.

Paper icon

Migration to Maven Central

Library has been moved to Maven Central since service ends for JCenter. Note that group id has been changed to io.github.pilgr. See the updated section below.

Add dependency

implementation 'io.github.pilgr:paperdb:2.7.2'

RxJava wrapper for Paper is available as a separate lib RxPaper2. Thanks @pakoito for it!

Initialize Paper

Should be initialized once in Application.onCreate():

Paper.init(context);

Threading

  • Paper.init() should be called in UI thread;
  • All other APIs (write, read etc.) are thread-safe and obviously must be called outside of UI thread. Reading/writing for different keys can be done in parallel.

Save

Save any object, Map, List, HashMap etc. including all internal objects. Use your existing data classes as is. Note that key is used as file name to store the data and so cannot contain symbols like /.

List<Person> contacts = ...
Paper.book().write("contacts", contacts);

Read

Read data objects is as easy as

List<Person> = Paper.book().read("contacts");

the instantiated class is exactly the one used to save data. Limited changes to the class structure are handled automatically. See Handle data class changes.

Use default values if object doesn't exist in the storage.

List<Person> = Paper.book().read("contacts", new ArrayList<>());

Delete

Delete data for one key.

Paper.book().delete("contacts");

Remove all keys for the given Book. Paper.init() must be called prior calling destroy().

Paper.book().destroy();

Use custom book

You can create custom Book with separate storage using

Paper.book("for-user-1").write("contacts", contacts);
Paper.book("for-user-2").write("contacts", contacts);

Each book is located in a separate file folder.

Get all keys

Returns all keys for objects in the book.

List<String> allKeys = Paper.book().getAllKeys();

Handle data structure changes

You can add or remove fields to the class. Then on next read attempt of a new class:

  • Newly added fields will have their default values.
  • Removed field will be ignored.

Note: field type changes are not supported.

For example, if you have following data class saved in Paper storage:

class Volcano {
    public String name;
    public boolean isActive;
}

And then you realized you need to change the class like:

class Volcano {
    public String name;
    // public boolean isActive; removed field
    public Location location; // New field
}

the isActive field will be ignored on next read and new location field will have its default value as null.

Exclude fields

Use transient keyword for fields which you want to exclude from saving process.

public transient String tempId = "default"; // Won't be saved

Set storage location for Book instances

By default, all the Paper data files are located with all files belonging to your app, at ../you-app-package-name/files. To save data on SDCard or at any other location you can use new API:

  • Paper.bookOn("/path/to/the/new/location")
  • or Paper.bookOn("path/to/the/new/location", "book-for-user-1") to create custom book.

Export/Import

  • Use Paper.book().getPath() to get path for a folder containing all *.pt files for a given book.
  • Use Paper.book().getPath(key) to get path for a particular *.pt file containing saved object for a given key. Feel free to copy/rewrite those files for export/import purposes. It's your responsibility to finalize file's export/import operations prior accessing data over Paper API.

Proguard config

  • Keep your data classes from modification by Proguard:
-keep class your.app.data.model.** { *; }

also you can implement Serializable for all your data classes and keep all of them using:

-keep class * implements java.io.Serializable { *; }
  • If your data models use enums, you should also keep them:
-keep enum your.app.data.model.** { *; }
  • And if you rely on Kotlin's emptyList()/emptyMap()/emptySet to assign values to your data models, it is relevant to keep EmptyList/EmptyMap/EmptySet as well:
-keep class kotlin.collections.* { *; }

How it works

Paper is based on the following assumptions:

  • Datasets on mobile devices are small and usually don't have relations in between;
  • Random file access on flash storage is very fast;

Paper saves each object for given key in a separate file and every write/read operations write/read the whole file.

The Kryo is used for object graph serialization and to provide data compatibility support.

Benchmark results

Running Benchmark on Nexus 4, in ms:

Benchmark Paper Hawk
Read/write 500 contacts 187 447
Write 500 contacts 108 221
Read 500 contacts 79 155

Limitations

  • Circular references are not supported

Apps using Paper

  • AppDialer – Paper initially has been developed as internal lib to reduce start up time for AppDialer. Currently AppDialer has the best start up time in its class. And simple no-sql-pain data storage layer like a bonus.
  • Busmap - This application provide all things you need for travelling by bus in Ho Chi Minh city, Vietnam. While the source code is not opened, it is found that the application use Paper internally to manange the bus stop data, route data, time data,... and more.

License

Copyright 2015 Aleksey Masny

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

paper's People

Contributors

ajriverav avatar amartinz avatar arok avatar cezar-carneiro avatar denis256 avatar filipebrandao avatar hiperioncn avatar johnjohndoe avatar kitwtnb avatar libraua avatar luong-komorebi avatar martinbonnin avatar mohamedwael avatar nabil6391 avatar pilgr avatar serveravt avatar thisisareku avatar wellguimaraes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

paper's Issues

PaperDbException in Android O

I updated my Nexus 5X to Android O today and found that some of my stuff doesn't work. I found out that I get a io.paperdb.PaperDbException: Couldn't read/deserialize file /data/user/0/at.schneider_holding.candidate/files/LookmodePersistence/INVOLVED.pt for table INVOLVED

(I have several Books open for different List-Objects)

full stacktrace here: at.schneider_holding.candidate_issue_1651_error_59649C08039B00012897608726AF1FFD_9b898de9661c11e7bc1556847afe9799_7_v2.txt

KryoException on read

I'm using Paper 2.0 and facing a rare crash for some users. Here's the log of Crashlytics:

Caused by com.esotericsoftware.kryo.KryoException
com.esotericsoftware.kryo.io.Input.require (Input.java:199)
com.esotericsoftware.kryo.io.Input.readVarInt (Input.java:373)
com.esotericsoftware.kryo.util.DefaultClassResolver.readClass (DefaultClassResolver.java:127)
com.esotericsoftware.kryo.Kryo.readClass (Kryo.java:693)
com.esotericsoftware.kryo.serializers.ObjectField.read (ObjectField.java:118)
com.esotericsoftware.kryo.serializers.FieldSerializer.read (FieldSerializer.java:540)
com.esotericsoftware.kryo.Kryo.readObject (Kryo.java:712)
io.paperdb.DbStoragePlainFile.readTableFile (DbStoragePlainFile.java:248)
io.paperdb.DbStoragePlainFile.readTableFile (DbStoragePlainFile.java:257)
io.paperdb.DbStoragePlainFile.readTableFile (DbStoragePlainFile.java:235)
io.paperdb.DbStoragePlainFile.select (DbStoragePlainFile.java:147)
io.paperdb.Book.read (Book.java:67)

Any help would be really appreciated.

Some change listener

It would be good to implement some change listener, which would be listening to any change made on storage...

Feature proposal: creating listener for data changes

Hello,

Thanks for sharing an interesting library!

What do you think about creating a listener for data changes? I think, it's missing, but quite useful feature. We can invoke methods (or single method) from a potential listener interface in write(...) and delete(...) methods. Let me know about your opinion and I can even create a small PR in a free time.
:-)

Regards,
Piotr

Unable to read data from paper book after app upgrade

Here's the unobfuscated stack trace. Could you offer any insight into why this might be happening?

Process: com.aashreys.walls.release, PID: 10063
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.aashreys.walls.release/com.aashreys.walls.ui.StreamActivity}: io.paperdb.PaperDbException: Couldn't read/deserialize file /data/user/0/com.aashreys.walls.release/files/collections_book/type_unsplash_collection767186.pt for table type_unsplash_collection767186
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
        at android.app.ActivityThread.-wrap12(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6119)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
     Caused by: io.paperdb.PaperDbException: Couldn't read/deserialize file /data/user/0/com.aashreys.walls.release/files/collections_book/type_unsplash_collection767186.pt for table type_unsplash_collection767186
        at io.paperdb.DbStoragePlainFile.readTableFile(DbStoragePlainFile.java:268)
        at io.paperdb.DbStoragePlainFile.readTableFile(DbStoragePlainFile.java:257)
        at io.paperdb.DbStoragePlainFile.readTableFile(DbStoragePlainFile.java:235)
        at io.paperdb.DbStoragePlainFile.select(DbStoragePlainFile.java:147)
        at io.paperdb.Book.read(Book.java:67)
        at com.aashreys.walls.persistence.a.b.b(CollectionRepositoryImpl.java:82)
        at com.aashreys.walls.ui.q.a(StreamActivityModel.java:67)
        at com.aashreys.walls.ui.StreamActivity.j(StreamActivity.java:108)
        at com.aashreys.walls.ui.StreamActivity.o(StreamActivity.java:40)
        at com.aashreys.walls.ui.d.onCreate(BaseActivity.java:54)
        at com.aashreys.walls.ui.StreamActivity.onCreate(StreamActivity.java:61)
        at android.app.Activity.performCreate(Activity.java:6679)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6119) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
     Caused by: com.esotericsoftware.kryo.KryoException: java.lang.IllegalArgumentException: field com.aashreys.walls.domain.display.collections.UnsplashCollection.id has type com.aashreys.walls.domain.c.b, got com.aashreys.walls.domain.c.a
    Serialization trace:
    id (com.aashreys.walls.domain.display.collections.UnsplashCollection)
    mContent (io.paperdb.PaperTable)
        at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:144)
        at com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer.read(CompatibleFieldSerializer.java:147)
        at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:734)
        at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:125)
        at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:540)
        at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:712)
        at io.paperdb.DbStoragePlainFile.readTableFile(DbStoragePlainFile.java:248)
        	... 22 more
     Caused by: java.lang.IllegalArgumentException: field com.aashreys.walls.domain.display.collections.UnsplashCollection.id has type com.aashreys.walls.domain.c.b, got com.aashreys.walls.domain.c.a
        at java.lang.reflect.Field.set(Native Method)
        at com.esotericsoftware.kryo.serializers.ObjectField.setField(ObjectField.java:54)
        at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:137)
        	... 28 more

Crash: Class cannot be created (non-static member class)

My class contains an inner class ,shows below:

public class Question {
    public QNCmt entQNCmt;
    public String strLastUpdateDate;
    public String strDayDiffer;
    public String sWebLk;
    public int strPraiseNumber;
    public int strQuestionId;
    public String strQuestionTitle;
    public String strQuestionContent;
    public String strAnswerTitle;
    public String strAnswerContent;
    public String strQuestionMarketTime;
    public String sEditor;

    public class QNCmt {
        public String strCnt;
        public String strId;
        public String strD;
        public String pNum;
        public String upFg;
    }
}

When restoring local data to this class ,it crashes.

 Caused by: com.esotericsoftware.kryo.KryoException: Class cannot be created (non-static member class): studio.uphie.one.ui.question.Question$QNCmt
                                                              Serialization trace:
                                                              entQNCmt (studio.uphie.one.ui.question.Question)
                                                              mContent (io.paperdb.PaperTable)
                                                                  at com.esotericsoftware.kryo.Kryo$DefaultInstantiatorStrategy.newInstantiatorOf(Kryo.java:1267)
                                                                  at com.esotericsoftware.kryo.Kryo.newInstantiator(Kryo.java:1075)
                                                                  at com.esotericsoftware.kryo.Kryo.newInstance(Kryo.java:1084)
                                                                  at com.esotericsoftware.kryo.serializers.FieldSerializer.create(FieldSerializer.java:570)
                                                                  at com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer.read(CompatibleFieldSerializer.java:68)
                                                                  at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:708)
                                                                  at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:125)
                                                                  at com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer.read(CompatibleFieldSerializer.java:110)
                                                                  at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:708)
                                                                  at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:125)
                                                                  at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:551)
                                                                  at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:686)
                                                                  at io.paperdb.DbStoragePlainFile.readTableFile(DbStoragePlainFile.java:222)
                                                                    ... 29 more

Doesn't paper support classes with inner classes in ?

And, I have a suggestion that paper adds a data-expire function :)

Couldn't create Paper dir

Hi!
Sometimes I have an exception: Exception java.lang.RuntimeException: Couldn't create Paper dir.
What can I do to avoid this exception?

Error reading object with Bitmap inside

I get an error when reading an object with a Bitmap field, the error thrown is:
*"You have to add a public no-arg constructor for the class android.graphics.Bitmap"
The StackTrace:
mContent (io.paperdb.PaperTable)
Read more: https://github.com/pilgr/Paper#save
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2936)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2965)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1406)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5371)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
Caused by: io.paperdb.PaperDbException: You have to add a public no-arg constructor for the class android.graphics.Bitmap

I can't add a constructor to the Bitmap class

java.lang.OutOfMemoryError when reading an object from Paper.

A user object saved in Paper was refactored (long ID field was replaced with String ID). Now when trying to read an object from Paper the following exception occurs:

java.lang.OutOfMemoryError
                      at com.esotericsoftware.kryo.io.Input.readString(Input.java:482)
                      at com.esotericsoftware.kryo.serializers.DefaultSerializers$StringSerializer.read(DefaultSerializers.java:195)
                      at com.esotericsoftware.kryo.serializers.DefaultSerializers$StringSerializer.read(DefaultSerializers.java:184)
                      at com.esotericsoftware.kryo.Kryo.readObjectOrNull(Kryo.java:763)
                      at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:132)
                      at com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer.read(CompatibleFieldSerializer.java:110)
                      at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:708)
                      at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:125)
                      at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:551)
                      at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:686)
                      at io.paperdb.DbStoragePlainFile.readTableFile(DbStoragePlainFile.java:239)
                      at io.paperdb.DbStoragePlainFile.select(DbStoragePlainFile.java:147)
                      at io.paperdb.Book.read(Book.java:67)

Encryption

Can it encrypt files ? From security point of view it's kind'a important.
If yes then what encryption it uses ?
pls respond.

Use consumerProguard

Use consumer proguard to android build tools to automatically merge your proguard rules.

Rewriting

What happens if I rewrite an existing key?
Does it substitute the old data or it appends the new one to the old one?

Error:Conflict with dependency 'org.ow2.asm:asm'

Every time I try to build my project I get this error: Error:Conflict with dependency 'org.ow2.asm:asm'. Resolved versions for app (5.0.3) and test app (5.0.1) differ. See http://g.co/androidstudio/app-test-app-conflict for details.

Here's my dependencies...

dependencies {
  compile fileTree(dir: 'libs', include: ['*.jar'])

  compile 'com.android.support:appcompat-v7:24.0.0'
  compile 'com.android.support:design:24.0.0'
  compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

  compile 'com.google.android.gms:play-services-auth:9.0.2'

  compile 'com.google.dagger:dagger:2.0'
  kapt 'com.google.dagger:dagger-compiler:2.0'
  provided 'org.glassfish:javax.annotation:10.0-b28'

  compile 'com.squareup.picasso:picasso:2.5.2'

  compile 'io.paperdb:paperdb:1.5'

  testCompile "org.robolectric:robolectric:3.1.1"
  testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
  testCompile "org.hamcrest:hamcrest-core:1.1"
  testCompile "org.hamcrest:hamcrest-library:1.1"
  testCompile "org.hamcrest:hamcrest-integration:1.1"
//  testCompile "org.mockito:mockito-core:2.0.+"
  testCompile "org.powermock:powermock-module-junit4:1.6.4"
  testCompile "org.powermock:powermock-module-junit4-rule:1.6.4"
  testCompile "org.powermock:powermock-api-mockito:1.6.4"
  testCompile "org.powermock:powermock-classloading-xstream:1.6.4"
  testCompile 'junit:junit:4.12'
}

File not found exception while saving table

The use case is quite simple: save a value to the database. The saving process works most of the time, but it's not consistent. I do have permissions for READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE.

I believe this may be a device-specific issue. The device is a Samsung Samsung Galaxy Tab S2 9.7 (SM-T810).

05-16 06:37:39.383 31449-31977/com.my.app W/System.err:   io.paperdb.PaperDbException: Couldn't save table: my_table. Backed up table will be used on next read attempt
05-16 06:37:39.383 31449-31977/com.my.app W/System.err:     at io.paperdb.DbStoragePlainFile.writeTableFile(DbStoragePlainFile.java:229)
05-16 06:37:39.383 31449-31977/com.my.app W/System.err:     at io.paperdb.DbStoragePlainFile.insert(DbStoragePlainFile.java:127)
05-16 06:37:39.383 31449-31977/com.my.app W/System.err:     at io.paperdb.Book.write(Book.java:36)
05-16 06:37:39.383 31449-31977/com.my.app W/System.err:     at com.pacoworks.rxpaper.RxPaperBook$1.call(RxPaperBook.java:155)
05-16 06:37:39.383 31449-31977/com.my.app W/System.err:     at rx.Completable$8.call(Completable.java:487)
05-16 06:37:39.383 31449-31977/com.my.app W/System.err:     at rx.Completable$8.call(Completable.java:481)
05-16 06:37:39.383 31449-31977/com.my.app W/System.err:     at rx.Completable.subscribe(Completable.java:1970)
05-16 06:37:39.383 31449-31977/com.my.app W/System.err:     at rx.Completable$29$1.call(Completable.java:2041)
05-16 06:37:39.383 31449-31977/com.my.app W/System.err:     at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:222)
05-16 06:37:39.383 31449-31977/com.my.app W/System.err:     at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
05-16 06:37:39.383 31449-31977/com.my.app W/System.err:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
05-16 06:37:39.383 31449-31977/com.my.app W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
05-16 06:37:39.383 31449-31977/com.my.app W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
05-16 06:37:39.383 31449-31977/com.my.app W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
05-16 06:37:39.383 31449-31977/com.my.app W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
05-16 06:37:39.383 31449-31977/com.my.app W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.lang.Thread.run(Thread.java:818)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:   Caused by: java.io.FileNotFoundException: /data/data/com.my.app/files/highlights/athlete_highlights.pt: open failed: ENOENT (No such file or directory)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:456)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:72)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at io.paperdb.DbStoragePlainFile.writeTableFile(DbStoragePlainFile.java:209)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at io.paperdb.DbStoragePlainFile.insert(DbStoragePlainFile.java:127)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at io.paperdb.Book.write(Book.java:36)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at com.pacoworks.rxpaper.RxPaperBook$1.call(RxPaperBook.java:155)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at rx.Completable$8.call(Completable.java:487)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at rx.Completable$8.call(Completable.java:481)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at rx.Completable.subscribe(Completable.java:1970)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at rx.Completable$29$1.call(Completable.java:2041)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:222)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.lang.Thread.run(Thread.java:818)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:   Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at libcore.io.Posix.open(Native Method)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:442)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:72)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at io.paperdb.DbStoragePlainFile.writeTableFile(DbStoragePlainFile.java:209)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at io.paperdb.DbStoragePlainFile.insert(DbStoragePlainFile.java:127)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at io.paperdb.Book.write(Book.java:36)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at com.pacoworks.rxpaper.RxPaperBook$1.call(RxPaperBook.java:155)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at rx.Completable$8.call(Completable.java:487)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at rx.Completable$8.call(Completable.java:481)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at rx.Completable.subscribe(Completable.java:1970)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at rx.Completable$29$1.call(Completable.java:2041)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:222)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
05-16 06:37:39.388 31449-31977/com.my.app W/System.err:     at java.lang.Thread.run(Thread.java:818)

Speed up concurrent read/writes for different keys

I saved a list use Paper.
The size of list about 5000, just a simple bean.
When I read the list from Paper, about spend 15s,
Is it very slow for this case?
The bean like this:
public class Comments implements Serializable {
private static final long serialVersionUID = -1291325341797562204L;
private String Comment;
private boolean flag;
private String user;
private Integer UserID;
private Long TS;
private String id;
}

Provide default PreferenceDataStore implementation

In Android O, individual preferences or even the entire PreferenceManager can call setPreferenceDataStore(), allowing your app to keep the same simple key/value pair API, but provide your own mechanism for storing the underlying data.

The interface is quite simple, it shouldn't take long to write. My time is limited right now, and if yours is too we'll have to wait until either of us is freed :D

https://developer.android.com/reference/android/preference/PreferenceDataStore.html

Custom storage location

Please add a method which allows selecting a custom location for books? (e.g. on the sdcard)

Retrieve files saved by Paper

Is there a way to retrieve the files saved by Paper? My scenario is that i would like to store the saved files in the cloud to serve as backup.

want to add that i did see a get file something method in one of the classes but it is private.

Can not set Kyro log level

Currently the internal kryo instance is not exposed (correct behavior), so there is no way to set the kyro log level to debug issues during serialization.

It would be useful for debugging to do Paper.logLevel(DEBUG) which would call to "Kryo.Log.DEBUG()".

kryo-4.0.0 upgradation

Hey Pilgr,

Your library is just awesome, we are using it in our many projects.
when we get next version with kryo-4.0.0?

android:allowBackup should not be used in library

Error:Execution failed for task ':app:processInternalConfigDebugManifest'.

Manifest merger failed : Attribute application@allowBackup value=(false) from AndroidManifest.xml:36:9-36
is also present at [io.paperdb:paperdb:1.1] AndroidManifest.xml:11:18-44 value=(true).
Suggestion: add 'tools:replace="android:allowBackup"' to element at AndroidManifest.xml:34:5-101:19 to override.

even lint suggestion will not help.

Race conditions

Paper looks very interesting, but I have some questions about how the file access works. It says random file access is rapid on flash storage. What happens if 2 async tasks read the file and write to the file making the first write to the file obsolete? The second write was based on the result before the first write when it probably should've been based on that after the first write. Does Paper handle these issues or do we have to make sure ourselves that that doesn't happen?

Exited with no zero value.

In two of my project I am getting java.exe exited with no zero value when gradle:appDebug after addin Paper dependency. Although I love this project this issue prevents me using this project. I thinks it crosses 65k method limit after using this library.

ClassCastException while reading JSON.

Hey. I am saving and reading a json in a book.

If I read the json back from the book directly it shows a ClassCastException for String to JSONObject

JSONObject userModelJson = Paper.book(BaseConstants.SESSION_BOOK)
                    .read(BaseConstants.SESSION_START_USER_MODEL);

but if I read it as a String and then convert it to JSON using JSONObject API, it succeeds.

String userModelString = Paper.book(BaseConstants.SESSION_BOOK)
                    .read(BaseConstants.SESSION_START_USER_MODEL);

JSONObject userModelJson = new JSONObject(userModelString);

Sample Json

{
  "address": [
    {
      "address": "full address here",
      "latitude": "0.0",
      "longitude": "0.0"
    }
  ],
  "email": "[email protected]",
  "name": "Sample",
  "phone": "1231231230",
  "username": "sampleuser"
}

Crash - Create Dir Paper

Hi,

This error started happening frequently in my application, I would like to know if there is anything I can do to prevent it from occurring.

Fatal Exception: java.lang.RuntimeException: Couldn't create Paper dir: /data/data/com.hotmart.sparkle/files/Notification
       at io.paperdb.DbStoragePlainFile.createPaperDir(DbStoragePlainFile.java:288)
       at io.paperdb.DbStoragePlainFile.assertInit(DbStoragePlainFile.java:278)
       at io.paperdb.DbStoragePlainFile.getAllKeys(DbStoragePlainFile.java:160)
       at io.paperdb.Book.getAllKeys(Book.java:96)
       at br.com.hotmart.hifire.util.storage.impl.BaseStorageAbstract.findAll(BaseStorageAbstract.java:78)
       at br.com.hotmart.hifire.util.NotificationUtils.show(NotificationUtils.java:50)
       at br.com.hotmart.hifire.v1.gcm.model.NewPostInTrackPayload.takeAction(NewPostInTrackPayload.java:37)
       at br.com.hotmart.hifire.v1.gcm.model.GcmMessage.takeAction(GcmMessage.java:105)
       at br.com.hotmart.hifire.v1.gcm.GcmListenerServiceImpl.onMessageReceived(GcmListenerServiceImpl.java:62)
       at com.google.android.gms.gcm.GcmListenerService.zzo(Unknown Source)
       at com.google.android.gms.gcm.GcmListenerService.zzn(Unknown Source)
       at com.google.android.gms.gcm.GcmListenerService.zzm(Unknown Source)
       at com.google.android.gms.gcm.GcmListenerService.zza(Unknown Source)
       at com.google.android.gms.gcm.GcmListenerService$1.run(Unknown Source)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
       at java.lang.Thread.run(Thread.java:818)

Paper trapped in recursive calls

Hi guys, is there anybody who can help me with this error?
I suspect it is trapped in recursive calls. any idea how to fix this?

07-14 00:03:44.102  24180-24180/com.application.android.myapplication E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.application.android.myapplication, PID: 24180
    java.lang.StackOverflowError
            at com.esotericsoftware.kryo.io.Output.flush(Output.java:181)
            at com.esotericsoftware.kryo.io.Output.require(Output.java:160)
            at com.esotericsoftware.kryo.io.Output.writeBytes(Output.java:246)
            at com.esotericsoftware.kryo.io.Output.write(Output.java:214)
            at com.esotericsoftware.kryo.io.Output.flush(Output.java:181)
            at com.esotericsoftware.kryo.io.OutputChunked.flush(OutputChunked.java:63)
            at com.esotericsoftware.kryo.io.Output.require(Output.java:160)
            at com.esotericsoftware.kryo.io.Output.writeBytes(Output.java:246)
            at com.esotericsoftware.kryo.io.Output.write(Output.java:214)
            at com.esotericsoftware.kryo.io.Output.flush(Output.java:181)
            at com.esotericsoftware.kryo.io.OutputChunked.flush(OutputChunked.java:63)
            at com.esotericsoftware.kryo.io.Output.require(Output.java:160)
            at com.esotericsoftware.kryo.io.Output.writeBytes(Output.java:246)
            at com.esotericsoftware.kryo.io.Output.write(Output.java:214)
            at com.esotericsoftware.kryo.io.Output.flush(Output.java:181)
            at com.esotericsoftware.kryo.io.OutputChunked.flush(OutputChunked.java:63)
            at com.esotericsoftware.kryo.io.Output.require(Output.java:160)
            at com.esotericsoftware.kryo.io.Output.writeBytes(Output.java:246)
            at com.esotericsoftware.kryo.io.Output.write(Output.java:214)
            at com.esotericsoftware.kryo.io.Output.flush(Output.java:181)
            at com.esotericsoftware.kryo.io.OutputChunked.flush(OutputChunked.java:63)
            at com.esotericsoftware.kryo.io.Output.require(Output.java:160)
            at com.esotericsoftware.kryo.io.Output.writeBytes(Output.java:246)
            at com.esotericsoftware.kryo.io.Output.write(Output.java:214)
            at com.esotericsoftware.kryo.io.Output.flush(Output.java:181)
            at com.esotericsoftware.kryo.io.OutputChunked.flush(OutputChunked.java:63)
            at com.esotericsoftware.kryo.io.Output.require(Output.java:160)
            at com.esotericsoftware.kryo.io.Output.writeBytes(Output.java:246)
            at com.esotericsoftware.kryo.io.Output.write(Output.java:214)
            at com.esotericsoftware.kryo.io.Output.flush(Output.java:181)
            at com.esotericsoftware.kryo.io.OutputChunked.flush(OutputChunked.java:63)
            at com.esotericsoftware.kryo.io.Output.require(Output.java:160)
            at com.esotericsoftware.kryo.io.Output.writeBytes(Output.java:246)
            at com.esotericsoftware.kryo.io.Output.write(Output.java:214)
            at com.esotericsoftware.kryo.io.Output.flush(Output.java:181)
            at com.esotericsoftware.kryo.io.OutputChunked.flush(OutputChunked.java:63)
            at com.esotericsoftware.kryo.io.Output.require(Output.java:160)
            at com.esotericsoftware.kryo.io.Output.writeBytes(Output.java:246)
            at com.esotericsoftware.kryo.io.Output.write(Output.java:214)
            at com.esotericsoftware.kryo.io.Output.flush(Output.java:181)
            at com.esotericsoftware.kryo.io.OutputChunked.flush(OutputChunked.java:63)
            at com.esotericsoftware.kryo.io.Output.require(Output.java:160)
            at com.esotericsoftware.kryo.io.Output.writeBytes(Output.java:246)
            at com.esotericsoftware.kryo.io.Output.write(Output.java:214)
            at com.esotericsoftware.kryo.io.Output.flush(Output.java:181)
            at com.esotericsoftware.kryo.io.OutputChunked.flush(OutputChunked.java:63)
            at com.esotericsoftware.kryo.io.Output.require(Output.java:160)
            at com.esotericsoftware.kryo.io.Output.writeBytes(Output.java:246)
            at com.esotericsoftware.kryo.io.Output.write(Output.java:214)
            at com.esotericsoftware.kryo.io.Output.flush(Output.java:181)
            at com.esotericsoftware.kryo.io.OutputChunked.flush(OutputChunked.java:63)
            at com.esotericsoftware.kryo.io.Output.require(Output.java:160)
            at com.esotericsoftware.kryo.io.Output.writeBytes(Output.java:246)
            at com.esotericsoftware.kryo.io.Output.write(Output.java:214)
            at com.esotericsoftware.kryo.io.Output.flush(Output.java:181)
            at com.esotericsoftware.kryo.io.OutputChunked.flush(OutputChunked.java:63)
            at com.esotericsoftware.kryo.io.Output.require(Output.java:160)
            at com.esotericsoftware.kryo.io.Output.writeBytes(Output.java:246)
            at com.esotericsoftware.kryo.io.Output.write(Output.java:214)
    at

Couldn't read/deserialize file

Couldn't read/deserialize file /data/user/0/files/io.paperdb/full_user.pt for table full_user

{
"data": {
"__v": "18",
"_id": "
_",
"contact_moods": [],
"contacts": {
"registered_contacts": [
{
"_id": "_
_",
"checked": false,
"color": 0,
"phone_number": "+_
_"
},
{
"_id": "
_
_",
"checked": false,
"color": 0,
"phone_number": "+_
_"
},
{
"_id": "_
********",
"checked": false,
"color": 0,
"phone_number": "+**
***_"
}
]
},
"country": "EG",
"custom_moods": [
{
"_id": "569f66b9a3479e330e47e28b",
"_mizo": {
"_gif": "/happy.mp4",
"_id": "569e3ecf0bd1d68f5d9e3314",
"_owner": "66609fe0-beb3-11e5-99d0-553ae763ee48",
"checked": false,
"created_at": "2016-01-19T13:49:03.070Z",
"is_preset": false,
"is_published": false,
"liked_by": [],
"reported_by": [],
"tags": [],
"text": "happy",
"textAttr": {
"text_color_index": -16777216,
"text_position_x": 20,
"text_position_y": 20,
"text_size_index": 1
},
"upload_state": "COMPLETED",
"used_by": []
},
"contacts": [],
"groups": [],
"is_enabled": true,
"is_global": false,
"name": "Feeling happy"
},
{
"_id": "569f6ebea3479e330e47e293",
"_mizo": {
"_gif": "/89d4a24f-76f3-41fa-a747-b2a5ff340dd4-1453287075597.jpg",
"_id": "569f67b4a3479e330e47e28f",
"_owner": "66609fe0-beb3-11e5-99d0-553ae763ee48",
"checked": false,
"created_at": "2016-01-20T10:55:48.818Z",
"is_preset": false,
"is_published": false,
"liked_by": [],
"reported_by": [],
"tags": [],
"text": "",
"textAttr": {
"text_color_index": -16777216,
"text_position_x": 0,
"text_position_y": 0,
"text_size_index": 1
},
"upload_state": "COMPLETED",
"used_by": []
},
"contacts": [],
"groups": [],
"is_enabled": true,
"is_global": false,
"name": ""
}
],
"gcm_reg_id": "_
_",
"groups": [],
"phone_number": "+2_
_
",
"public_mood": {
"_mizo": {
"_gif": "/cold.mp4",
"_id": "569f6ebea3479e330e47e292",
"owner": "66609fe0-beb3-11e5-99d0-553ae763ee48",
"checked": false,
"created_at": "2016-01-20T11:25:46.566Z",
"is_preset": false,
"is_published": false,
"liked_by": [],
"reported_by": [],
"tags": [],
"text": "",
"textAttr": {
"text_color_index": -16777216,
"text_position_x": 0,
"text_position_y": 0,
"text_size_index": 1
},
"upload_state": "COMPLETED",
"used_by": []
},
"is_enabled": true,
"is_global": false,
"name": ""
},
"settings": {
"is_mood_visible_for_contacts_only": false,
"is_sync_on_wifi_only": false,
"language": "EN"
},
},
"isNew": false,
"message": "success"
}

KryoException: Buffer underflow

Very rarely crash happening in AppDialer app using Paper, affects only 0,05% sessions.

Caused by: com.esotericsoftware.kryo.KryoException: Buffer underflow.
Serialization trace:
a (io.paperdb.PaperTable)
       at com.esotericsoftware.kryo.io.Input.require(Input.java:199)
       at com.esotericsoftware.kryo.io.Input.readVarInt(Input.java:373)
       at com.esotericsoftware.kryo.util.DefaultClassResolver.readClass(DefaultClassResolver.java:127)
       at com.esotericsoftware.kryo.Kryo.readClass(Kryo.java:667)
       at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:118)
       at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:557)
       at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:686)
       at io.paperdb.DbStoragePlainFile.readTableFile(DbStoragePlainFile.java:204)
       at io.paperdb.DbStoragePlainFile.select(DbStoragePlainFile.java:128)
       at io.paperdb.Paper.get(Paper.java:52)
       at name.pilgr.appdialer.Storage.getHistory(Storage.java:54)
       at name.pilgr.appdialer.search.StatsManager.init(StatsManager.java:18)
       at name.pilgr.appdialer.Engine.setFire(Engine.java:197)
       at name.pilgr.appdialer.Engine.doStartUp(Engine.java:235)
       at name.pilgr.appdialer.Engine$1.run(Engine.java:70)
       at name.pilgr.appdialer.util.CrashableTask.run(CrashableTask.java:18)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
       at java.lang.Thread.run(Thread.java:841)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.