Saturday, February 1, 2020

Aleksandr Koscheev


LOOKING FOR A JOB


Right now I am in Cancún, Mexico.

Phones:

 (+521) 998 424 8890

Skype: ru.alxr

Email aleksandr.koscheev@gmail.com

LinkedIn profile: https://mx.linkedin.com/in/aleksandr-koscheev-b7260062

I am looking for job in Android development industry


Friday, March 16, 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 AutoValue

Let'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 - c
As 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 :
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

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.