【问题标题】:Passing Object as Params in AsyncTask在 AsyncTask 中将对象作为参数传递
【发布时间】:2019-02-01 07:19:41
【问题描述】:

我想使用AsyncTask 查询数据库。现在我可以选择为每种类型的查询创建不同的 AsyncTasks。我倾向于另一种选择是为每种类型的查询创建一个 AsyncTask。

如果我将参数作为对象传递,然后将它们转换回来,这是一种不好的做法吗?我会遇到一些麻烦吗?我应该在构造函数中传递所有内容吗?

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

【问题讨论】:

  • 您可以直接使用 Integer 代替对象,当它传递给 switch case 时无需强制转换它
  • 公共类 queryAsyncTask 扩展 AsyncTask { private ItemDao mAsyncDao; queryAsyncTask(ItemDao dao) { mAsyncDao = dao; } @Override protected Void doInBackground(Integer... integers) { switch (integers[0]) { case DELETE_QUERY: mAsyncDao.deleteItem((int) objects[1]);休息;案例 INSERT_QUERY: mAsyncDao.insert((Item) objects[1]);休息; } 返回空值; } }
  • 但是对于插入操作,我需要传递Item对象,仔细看。
  • 它没有相关性,但对于数据库操作,我认为最好的方法是String

标签: android object android-asynctask android-room


【解决方案1】:

如果我将参数作为对象传递,然后将它们转换回来,是这样吗? 不好的做法?我会遇到一些麻烦吗?我应该通过吗 构造函数中的所有内容?

是的,这是一种非常糟糕的做法。考虑您的以下代码:

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();

这比之前的代码更具可读性。

注意:所有代码尚未测试。

【讨论】:

  • 好的,我明白了。当项目很大时,它会降低可读性,并且其他贡献者更容易出错。
  • 反正我改成queryAsyncTask(mItemDao,INSERT_QUERY).execute(item);和 queryAsyncTask(mItemDao, DELETE_QUERY).execute(item);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-29
  • 1970-01-01
  • 1970-01-01
  • 2016-08-28
  • 2012-07-13
相关资源
最近更新 更多