Передача объекта как параметра в AsyncTask - PullRequest
0 голосов
/ 01 февраля 2019

Я хотел запросить базу данных, используя AsyncTask.Теперь у меня есть возможность сделать разные AsyncTasks для каждого типа запросов.Другой вариант, к которому я склонен, - создать по одному AsyncTask для каждого типа запроса.

Если я передаю params как объекты, а затем возвращаю их, это плохая практика?Могу ли я столкнуться с некоторыми проблемами?Должен ли я передать все в конструкторе?

public void insert (Item item){
    new queryAsyncTask(mItemDao).execute(INSERT_QUERY, item);
}

public void delete (int uid){
    new queryAsyncTask(mItemDao).execute(DELETE_QUERY, uid);
}

private static class queryAsyncTask extends AsyncTask<Object, Void, Void>{

    private ItemDao mAsyncDao;

    queryAsyncTask(ItemDao dao){
        mAsyncDao = dao;
    }

    @Override
    protected Void doInBackground(Object... objects) {
        switch ((int) objects[0]){
            case DELETE_QUERY:
                mAsyncDao.deleteItem((int)objects[1]);
                break;
            case INSERT_QUERY:
                mAsyncDao.insert((Item)objects[1]);
                break;
        }
        return null;
    }
}

1 Ответ

0 голосов
/ 01 февраля 2019

Если я передаю параметры как объекты, а затем возвращаю их обратно, это плохая практика?Могу ли я столкнуться с некоторыми проблемами?Должен ли я передавать все в конструктор?

Да, это очень плохая практика.Рассмотрим следующий ваш код:

private static class queryAsyncTask extends AsyncTask<Object, Void, Void>{

    private ItemDao mAsyncDao;

    queryAsyncTask(ItemDao dao){
        mAsyncDao = dao;
    }

    @Override
    protected Void doInBackground(Object... objects) {
        ...
    }
}

Затем вы можете вызвать его с помощью:

new queryAsyncTask(mItemDao).execute(DELETE_QUERY, uid);

или

new queryAsyncTask(mItemDao).execute(INSERT_QUERY, item);

, но затем вы также можете вызвать егос обоими из следующего:

new queryAsyncTask(mItemDao).execute(new Object(), item);
new queryAsyncTask(mItemDao).execute(new ArrayList<String>(), item);

, который не дал никакой ошибки вообще.Это потому, что ваш код не имел строгих ограничений и не дал достаточного объяснения того, что он делает.


Вам лучше составить каждую задачу для CRUD и передать значение (ссылка) через конструктор.Например, вы можете создать что-то вроде этого для INSERT:

private static class InsertQueryTask extends AsyncTask<Void, Void, Void> {

    private ItemDao mItemDao;
    private Item mItem;

    InsertQueryTask(ItemDao dao, Item item) {
        mItemDao = dao;
        mItem = item;
    }

    @Override
    protected Void doInBackground(Void... voids) {
       mItemDao.insert(mItem);
    }
}

, затем вы можете назвать его:

new InsertQueryTask(mItemDao, item).execute();

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

Вы можете дополнительно изменить свой код, чтобы сделать его Fluent Interface .Примерно так:

private static class InsertQueryTask extends AsyncTask<Void, Void, Void> {

    private ItemDao mItemDao;
    private Item mItem;

    InsertQueryTask(ItemDao dao) {
        mItemDao = dao;
    }

    InsertQueryTask with(Item item) {
      mItem = item;
      return this;
    }

    @Override
    protected Void doInBackground(Void... voids) {
       mItemDao.insert(mItem);
    }
}

Теперь вы можете вызвать его с помощью:

new InsertQueryTask(mItemDao).with(item).execute();

, который более читабелен, чем предыдущий код.

ПРИМЕЧАНИЕ: Весь код еще не проверен.

...