Уменьшите количество AsyncTask в репозитории базы данных комнаты - PullRequest
0 голосов
/ 20 апреля 2019

Я пытаюсь упростить количество строк для моих кодов в хранилище.В настоящее время в моих кодах много повторений.

Многие онлайн-решения включают в себя вставку только один раз в таблицу.Мне нужно сделать 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;
        }
    }

}

У меня все еще есть другие методы вставки, и янужно позвонить удалить и обновить, а также.Я не хочу, чтобы коды так повторялись

1 Ответ

0 голосов
/ 21 апреля 2019

Итак, @notTdar придумала это решение

Попросите вызов класса ThreadPoolExecutor.

Вызовите этот класс для выполнения всех DAO из базы данных комнат Android

  • Звоните 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");
        }
        });
        }
...