有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用AsyncTask的结果在其onPostExecute中运行for循环(再次异步)

我使用下面的代码从数据库中检索电话号码数据。在将其呈现给用户之前,我希望将每个PhoneNumber对象与其各自的联系人(存储在另一个表中)进行匹配,以便也向用户呈现检索到的电话号码的全名

当我需要再次查询数据库时,问题就出现了,因为我必须异步进行查询(否则应用程序会崩溃)。我还需要对每个PhoneNumber对象进行循环。我如何实现这一点

public List<PhoneNumber> fetchMatchingNumbers(final String phoneNumber) {
    new AsyncTask<Void, Void, List<PhoneNumber>>() {
        @Override
        protected List<PhoneNumber> doInBackground(Void... voids) {
            returnedNumbers = worksideDatabase.phoneNumberDao().getMatchingNumbers(phoneNumber);

            return null;
        }

        @Override
        protected void onPostExecute(List<PhoneNumber> phoneNumbers) {
            super.onPostExecute(phoneNumbers);

            // Clear the list each time the query is updated
            suggestedContactList.clear();

            for (PhoneNumber pn : returnedNumbers) {
                int id = pn.getContactId();
                String stringPN = pn.getPhoneNumber();

                // Change this to be a background thread!
                returnedFullName = worksideDatabase.contactDao().getFullNameByContactId(id);

                // TODO - match each PhoneNumber to its contact's name & surname
                SuggestedContactItem item =
                        new SuggestedContactItem(
                                returnedFullName, stringPN, pn.getPhoneNumberType());
                suggestedContactList.add(item);
            }
            adapter.notifyDataSetChanged();
        }
    }.execute();
    return returnedNumbers;
}

共 (2) 个答案

  1. # 1 楼答案

    为什么使用AsyncTask?它已经被弃用了,而且通常现在没有人使用它。 没有理由在小部件所在的活动/片段中执行此类代码。我建议首先使用一种MV*模式。例如,最好的是MVP。您可以使用以下界面创建类演示者:

    public class Presenter {
    
      private Activity activity;
    
      void attachActivity(Activity activity) {
        this.activity = activity;
      }
    
      void detachActivity() {
        this.activity = null;
      }
    
      void onPhoneNumberClick(String phoneNumber) {
    
      }
    }
    

    您应该在onStart()回调中将活动(片段)附加到其“presenter”,并在onStop()中分离。 当你的click listener事件发生时,你应该让演示者在
    onPhoneNumberClick方法。 那么你应该实现这个逻辑。你需要som异步工作。这可以通过运行新线程来实现,但是为了设置获取的数据,您必须将线程切换到main。现在,rxJava2是一种流行的机制,它可以让您在不启动线程的情况下实现异步工作。因此,使用rxJava2可以做到:

    void onPhoneNumberClick(String phoneNumber) {
        Single.fromCallable(() -> interactor.getSuggestedContactItems(phoneNumber))
            .subscribeOn(Schedulers.io()) // thread from poll IO where invokation happens
            .observeOn(AndroidSchedulers.mainThread()) // thread where result observed
            .subscribe( contactItems -> {
              if (activity != null) {
                activity.setContactList(contactItems);
              }
            });
      }
    

    在这里你可以看到新的实体交互器。它运行并完成了计算人员“通过一个电话号码获取建议联系人项目列表”的所有工作。但上面的代码只是展示了在rxJava2中切换线程进行计算和观察是多么容易

    最后,与你的目标互动:

    class Interactor {
      private WorksideDatabase worksideDatabase;
    
      Interactor(WorksideDatabase worksideDatabase) {
        this.worksideDatabase = worksideDatabase;
      }
    
      List<SuggestedContactItem> getSuggestedContactItems(String phoneNumber) {
        List<PhoneNumber> returnedNumbers = worksideDatabase.phoneNumberDao().getMatchingNumbers(phoneNumber);
        List<SuggestedContactItem> suggestedContactItems = new ArrayList<>();
        for (PhoneNumber pn : returnedNumbers) {
          int id = pn.getContactId();
          String stringPN = pn.getPhoneNumber();
    
          // Change this to be a background thread!
          String returnedFullName = worksideDatabase.contactDao().getFullNameByContactId(id);
    
          // TODO - match each PhoneNumber to its contact's name & surname
    
          SuggestedContactItem item =
              new SuggestedContactItem(
                  returnedFullName, stringPN, pn.getPhoneNumberType());
          suggestedContactItems.add(item);
        }
        return suggestedContactItems;
      }
    }
    

    所以在这里你可以独立测试所有行为。如果您同时需要电话号码和建议联系人项目的列表,则可以在Interactor中返回配对。它提供了更可靠的代码和更好的方法。 如果你有任何问题,请告诉我

  2. # 2 楼答案

    我不认为AsyncTask是完成这项任务的好工具,而且它已被弃用,请尝试使用RxJava,或者如果不想使用外部库,请使用java。util。并发/协同程序