减少Room数据库存储库中的AsyncTask数量

时间:2019-04-20 02:30:20

标签: java android android-room android-database

我正在尝试简化存储库中代码的行数。 目前,我的代码中有很多重复。

许多在线解决方案仅涉及一次插入表中。 我需要在许多表上执行insert()。我想减少重复编写同一内部AsyncTask的重复,以便将不同的数据插入到不同的表中

这是存储库类的代码

public class CharacterRepository {
    private UserDao rUserDao;
    private  CharacterDao rCharacterDao;
    private EquipementDao rEquipementDao;

    private LiveData<List<UserDao>> rUserLD;
    private LiveData<List<CharacterDao>> rCharacterLD;
    private LiveData<List<EquipmentDao>> rEquipmentLD;

    // Constructor that handles the database and initialise the member variables
    CharacterRepository(Application application){
        MyDatabase db = MyDatabase.getDatabase(application);
        rUserDao = db.userDao();
        rCharacterDao = db.characterDao();
        rEquipementDao = db.EquipmentDao();

        rUserLD = rUserDao.getAllUser();
        rCharacterLD = rCharacterDao.getAllChar();
        rEquipmentLD = rEquipementDao.getAllEquip();
    }

    // Wrapper method that returns cached entities as LiveData
    public LiveData<List<UserEntity>> getAllUser(){return rUserLD;}
    public LiveData<List<CharEntity>> getAllChar(){return rCharacterLD;}
    public LiveData<List<EquipEntity>> getAllEquip(){return rEquipmentLD;}

    /*---------------------the start of the problem-------------------*/
    //Wrapper method: calling insert on non-UI Thread
    public void insert(UserEntity userEntity){new insertUserAsyncTask(rUserDao).execute(userEntity);}
    public void insert(CharacterEntity characterEntity){new insertCharacterAsyncTask(rCharacterDao).execute(characterEntity);}
    public void insert(EquipmentEntity equipmentEntity){new insertEquipAsyncTask(rCharacterDao).execute(equipmentEntity);}


    /*-------------------THIS IS THE PART WHERE I WANT TO REDUCE THE CODE REDUNDANCY THE CODES ARE DOING THE SAME THING-------------------*/
    private static class insertUserAsyncTask extends AsyncTask<UserEntity, Void, Void> {
        private UserDao mAsyncTaskDao;

        insertUserAsyncTask(UserDao dao) {mAsyncTaskDao = dao;}

        @Override
        protected Void doInBackground(UserEntity... userEntities) {
            mAsyncTaskDao.save(params[0]);
            return null;
        }
    }
    private static class insertCharacterAsyncTask extends AsyncTask<CharacterEntity, Void, Void> {
        private CharacterDao mAsyncTaskDao;
        insertCharacterAsyncTask(CharacterDao dao) {mAsyncTaskDao = dao; }

        @Override
        protected Void doInBackground(CharacterEntity... characterEntities) {
            mAsyncTaskDao.save(params[0]);
            return null;
        }
    }
    private static class insertEquipAsyncTask extends AsyncTask<, Void, Void> {
        private EquipmentDao mAsyncTaskDao;
        insertEquipAsyncTask(EquipmentDao dao) {mAsyncTaskDao = dao;}

        @Override
        protected Void doInBackground(EquipmentEntity... equipmentEntities) {
            mAsyncTaskDao.save(params[0]);
            return null;
        }
    }

}

我还有其他插入方法,我也需要调用delete和update。我不希望代码如此重复

1 个答案:

答案 0 :(得分:0)

因此,@ notTdar提出了此解决方案

具有一个类调用ThreadPoolExecutor。

调用此类以执行Android Room数据库中的所有DAO

  • 致电cleanResource();中的onDestroy
  • 致电shut();中的onPause

ThreadPoolExecutorHelper.java

public class ThreadPoolExecutorHelper {
        private static final String TAG = ThreadPoolExecutorHelper.class.getSimpleName() + " : ";
        private static final boolean LOG_DEBUG = false;

        private static volatile ThreadPoolExecutorHelper INSTANCE;
        private ThreadPoolExecutor mThreadPoolExecutor;
        private BlockingQueue<Runnable> mBlockingQueue;
        private static final int TASK_QUEUE_SIZE = 12;

        //core size, keeps thread : along with running + idle
        private static final int CORE_POOL_SIZE = 5;

        // pool size
        private static final int MAX_POOL_SIZE = 5;

        // core pool size exceeds, idle thread will wait for this time before termination.
        private static final long KEEP_ALIVE_TIME = 20L;

        public static ThreadPoolExecutorHelper getInstance() {
            if (LOG_DEBUG) Log.e(TAG, "getInstance: ");
            if (INSTANCE == null) {
                synchronized (ThreadPoolExecutorHelper.class) {
                    if (INSTANCE == null) {
                        INSTANCE = new ThreadPoolExecutorHelper();
                    }
                }
            }
            return INSTANCE;
        }

        private ThreadPoolExecutorHelper() {
            if (LOG_DEBUG) Log.d(TAG, "ctor: ");
            initBlockingQueue();
            initThreadPoolExecutor();
        }

        // submit Runnables
        public void submitRunnable(Runnable task) {
            if (LOG_DEBUG) Log.d(TAG, "submitRunnable: " + task.getClass().getSimpleName());

            //in case, init again, if null.
            initBlockingQueue();
            initThreadPoolExecutor();
            mThreadPoolExecutor.execute(task);
        }

        // shut the threadpool
        public synchronized void shut() {
            if (LOG_DEBUG) Log.d(TAG, "shut: ");
            if (mThreadPoolExecutor != null) {
                mThreadPoolExecutor.shutdown();
                try {
                    mThreadPoolExecutor.awaitTermination(6000L, TimeUnit.SECONDS);
                } catch (InterruptedException e) {
                    if (LOG_DEBUG) Log.w(TAG, "shut: InterruptedException");
                    mThreadPoolExecutor.shutdownNow();
                }
            } else {
                Log.e(TAG, "shut: mThreadPoolExecutor instance NULL");
            }
        }

        //clean up
        public void cleanResources() {
            if (LOG_DEBUG) Log.e(TAG, "cleanResources: ");
            if (INSTANCE != null) {
                if (mThreadPoolExecutor != null) {
                    mThreadPoolExecutor = null;
                }
                if (mBlockingQueue != null) {
                    mBlockingQueue = null;
                }
                nullifyHelper();
            }
        }

        private static void nullifyHelper() {
            if (INSTANCE != null) {
                INSTANCE = null;
            }
        }

        private void initBlockingQueue() {
            if (mBlockingQueue == null) {
                mBlockingQueue = new LinkedBlockingQueue<>(TASK_QUEUE_SIZE);
            }
        }

        private void initThreadPoolExecutor() {
            if (mThreadPoolExecutor == null) {
                mThreadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE,
                        KEEP_ALIVE_TIME, TimeUnit.SECONDS, mBlockingQueue);
            }
        }
    }

将此代码添加到onCreate(活动)或onViewCreated(片段)中 这将通过调用ThreadPoolExecutorHelper

来初始化getInstance()
private void initExecutorHelper() {
    if (LOG_DEBUG) Log.d(TAG, "initExecutorHelper: ");
    if (mExecutorHelper == null) {
        mExecutorHelper = ThreadPoolExecutorHelper.getInstance();
    }
}

这是启动线程的insert();方法 您可以更改此设置,以便从会议室数据库中的DAO中进行插入,查询,删除任务

public void insert() {
        if (LOG_DEBUG) Log.d(TAG, "requestQREntityList: whatKind= " + whatKind);
        mExecutorHelper.submitRunnable(() -> {
        if (!Thread.interrupted()) {
        //request a list or inset something, write your logic.

        } else {
        if (LOG_DEBUG) Log.e(TAG, "run: Thread is interrupted");
        }
        });
        }