Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Room running very slow

I'm trying to get/store data using the Room Persistence Library. The calls to get all data from a table is really slow, and I timed it using nanoTime to be about 1800ms, which I think is too slow. What could be going wrong?

Here's some more info:

  1. There are just 20-30 entries in the table.
  2. 20 fields, some serialized by Gson. Gson is not the bottleneck (says nanoTime)
  3. Test device runs 6.0 (Xperia M5)
  4. Room v1.1.1
  5. Queries are running using AsyncTask

The query is defined in DbDao as

@Query("SELECT * FROM events")
List<Event> getAllEvents();
like image 252
pulsejet Avatar asked Jun 30 '18 12:06

pulsejet


1 Answers

Async task is not good for handling Room database. I would suggest you to use executor and make a singleton class using this. Code is as follows. import android.os.Looper; import android.support.annotation.NonNull;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class AppExecutor {
    private static final Object LOCK = new Object();
    private static AppExecutor sInstance;
    private final Executor diskIO;
    private final Executor mainThread;
    private final Executor networkIO;

    public AppExecutor(Executor diskIO, Executor mainThread,
                       Executor networkIO) {
        this.diskIO = diskIO;
        this.mainThread = mainThread;
        this.networkIO = networkIO;
    }

    public static AppExecutor getInstance() {
        if (sInstance == null) {
            synchronized (LOCK) {
                sInstance = new AppExecutor(Executors.newSingleThreadExecutor(),
                      Executors.newFixedThreadPool(3), new MainThreadExecutor());
            }
        }
        return sInstance;
    }

    public Executor diskIO() {
        return diskIO;
    }

    public Executor mainThread() {
        return mainThread;
    }

    public Executor networkIO() {
        return networkIO;
    }

    private static class MainThreadExecutor implements Executor {
        private android.os.Handler mainThreadHandler =
                new android.os.Handler(Looper.getMainLooper());

        @Override
        public void execute(@NonNull Runnable runnable) {
        }
    }
}

Now after making this new class do all database access functions in the appexecutor threads. This is better than using async task and built in java thread libraries. Also make sure that any data access functions does not run on UI thread. If you have posted more code I would be able to pinpoint the exact problem. One last thing use this in your code as follows-

AppExecutor.getInstance().diskIO().execute(new Runnable() {
    @Override
    public void run() {
        ///Your data access task////
    }
});
like image 199
Aryan Soni Avatar answered Sep 30 '22 21:09

Aryan Soni