减少 Room DataBase Repository 中 AsyncTask 的数量

Reduce the number of AsyncTask in Room DataBase Repository

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

网上的很多解决方案只涉及插入一次到table。 我需要在许多 table 上执行 insert()。我想减少重复编写相同的内部 AsyncTask 以将不同的数据插入不同的 table

这是存储库的代码 class

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;
        }
    }

}

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

所以,@notTdar 想出了这个解决方案

class 调用 ThreadPoolExecutor。

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

  • onDestroy
  • 中调用cleanResource();
  • onPause
  • 中调用shut();

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(activity)或onViewCreated(片段)中添加此代码 这将通过调用 getInstance()

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

这是启动线程的insert();方法 您可以将其更改为从 Room Database

中的 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");
        }
        });
        }