Tuesday, March 6, 2018
Tuesday, February 20, 2018
Realm and threads
Just created objects could be touched in any thread, framework does not mind.
new AsyncTask<Void, Void, Dummy>() {
@Override protected Dummy doInBackground(Void... voids) {
Dummy dummy = new Dummy("a", "b");
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
realm.insertOrUpdate(dummy);
realm.commitTransaction();
Debug
.get()
.with(
this,
"THREAD %s %s - %s",
Thread.currentThread().getName(),
dummy.getKey(),
dummy.getValue()
)
.log();
new Thread(new Runnable() {
@Override public void run() {
Debug
.get()
.with(
this,
"THREAD %s %s - %s",
Thread.currentThread().getName(),
dummy.getKey(),
dummy.getValue()
)
.log();
dummy.setValue("c");
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
realm.insertOrUpdate(dummy);
realm.commitTransaction();
Debug
.get()
.with(
this,
"UPDATED : THREAD %s %s - %s",
Thread.currentThread().getName(),
dummy.getKey(),
dummy.getValue()
)
.log();
}
}).start();
return dummy;
}
@Override protected void onPostExecute(Dummy dummy) {
Debug
.get()
.with(
this,
"THREAD %s %s - %s",
Thread.currentThread().getName(),
dummy.getKey(),
dummy.getValue()
)
.log();
}
}.execute();
Output is
THREAD AsyncTask #1 b - a
THREAD main b - a
THREAD Thread-6 b - a
UPDATED : THREAD Thread-6 b - c
Well, let's try to read the database.
new AsyncTask<Void, Void, Dummy>() {
@Override protected Dummy doInBackground(Void... voids) {
Realm realm = Realm.getDefaultInstance();
RealmQuery<Dummy> query = realm.where(Dummy.class);
List<Dummy> list = query.findAll();
Dummy result = null;
for (Dummy dummy : list){
result = dummy;
Debug
.get()
.with(
this,
"THREAD %s %s - %s",
Thread.currentThread().getName(),
dummy.getKey(),
dummy.getValue()
)
.log();
new Thread(new Runnable() {
@Override public void run() {
Debug
.get()
.with(
this,
"THREAD %s %s - %s",
Thread.currentThread().getName(),
dummy.getKey(),
dummy.getValue()
)
.log();
dummy.setValue("c");
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
realm.insertOrUpdate(dummy);
realm.commitTransaction();
Debug
.get()
.with(
this,
"UPDATED : THREAD %s %s - %s",
Thread.currentThread().getName(),
dummy.getKey(),
dummy.getValue()
)
.log();
}
}).start();
if (result != null) break;
}
return result;
}
@Override protected void onPostExecute(Dummy dummy) {
Debug
.get()
.with(
this,
"THREAD %s %s - %s",
Thread.currentThread().getName(),
dummy.getKey(),
dummy.getValue()
)
.log();
}
}.execute();
Output is
THREAD AsyncTask #1 b - c
java.lang.IllegalStateException: Realm access from incorrect thread.
Realm objects can only be accessed on the thread they were created.
OK, lets block onPostExecute.
All the same:
THREAD AsyncTask #1 b - c
java.lang.IllegalStateException: Realm access from incorrect thread.
Realm objects can only be accessed on the thread they were created.
OK, I can see, that you cannot touch RealmObject from different thread.Docs are right)))What to do?Realm offers AutoValueLet's try.Installation:Here is abstract DummyNotARealmObject class:
import com.google.auto.value.AutoValue; @AutoValuepublic abstract class DummyNotARealmObject{ public static DummyNotARealmObject create(String key, String value) { return new AutoValue_DummyNotARealmObject(key, value); } public abstract String getKey(); public abstract String getValue(); }... and modified asyncTask:new AsyncTask<Void, Void, DummyNotARealmObject>() { @Override protected DummyNotARealmObject doInBackground(Void... voids) { Realm realm = Realm.getDefaultInstance(); RealmQuery<Dummy> query = realm.where(Dummy.class); List<Dummy> list = query.findAll(); final DummyNotARealmObject result; for (Dummy dummy : list){ result = DummyNotARealmObject.create( dummy.getKey(), dummy.getValue() ); Debug .get() .with( this, "THREAD %s %s - %s", Thread.currentThread().getName(), dummy.getKey(), dummy.getValue() ) .log(); new Thread(new Runnable() { @Override public void run() { Debug .get() .with( this, "THREAD %s %s - %s", Thread.currentThread().getName(), result.getKey(), result.getValue() ) .log(); } }).start(); return result; } return null; } @Override protected void onPostExecute(DummyNotARealmObject dummy) { Debug .get() .with( this, "THREAD %s %s - %s", Thread.currentThread().getName(), dummy.getKey(), dummy.getValue() ) .log(); } }.execute();Output:THREAD AsyncTask #1 b - c THREAD main b - c THREAD Thread-6 b - cAs you can see, now we can easily get access to our Dummy-object's fields from another thread.All we need is to create abstract class and declare constructor and getters.This is not as simple as when we use SQLite but I guess Realm is worth it.
Friday, February 16, 2018
Tip: Use lambdas
The reason is that lambda does not hold strong reference and will not cause memory leak.
To use lambda just add following block :
To use lambda just add following block :
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
inside android {...} block of app level of your build.gradle file Wednesday, February 14, 2018
Another one navigation library
Another one not a Cicerone ))
https://github.com/aartikov/Alligator
https://github.com/aartikov/Alligator
Alligator is a modern Android navigation library that will help to organize your navigation code in clean and testable way.
Features
- Screens based on activities, fragments and dialog fragments.
- Simple yet powerful navigation methods.
- Independence from activity lifecycle (navigation is available even when an application is in background).
- Passing screen arguments without boilerplate code.
- Handling screen result in object oriented style.
- Screen switching with nested navigation.
- Flexible animation configuring.
Sunday, January 14, 2018
Friday, October 6, 2017
Subscribe to:
Posts (Atom)



