1

我是 Rx 编程的新手(到目前为止我玩得很开心^^)。我正在尝试将 AsyncTask 调用转换为 Rx 函数。

我的功能:

  • 获取所有已安装的应用
  • 标准化标签
  • 按字母顺序对所有内容进行排序
  • 按字母组排列它们(这是一个 Multimap(letter, list of apps))并将结果传递给适配器以显示所有内容。

以下是我到目前为止对 Rx 所做的事情:

Observable.from(getInstalledApps(getActivity(), false))
    .subscribeOn(Schedulers.newThread())
    .observeOn(AndroidSchedulers.mainThread())
    .map(new Func1<ResolvedActivityInfoWrapper, ResolvedActivityInfoWrapper>() {
      @Override
      public ResolvedActivityInfoWrapper call(ResolvedActivityInfoWrapper act) {
        // Normalize labels
act.setLabel(Normalizer.normalize(act.getLabel(getPackageManager()).replace(String.valueOf((char) 160), "").trim(), Normalizer.Form.NFD).replaceAll("\\p{M}", ""));
        return act;
      }
    })
    .toList()
    .subscribe(new Observer<List<ResolvedActivityInfoWrapper>>() {
      List<ResolvedActivityInfoWrapper> list;
      @Override
      public void onCompleted() {
        Observable.from(list).groupBy(new Func1<ResolvedActivityInfoWrapper, String>() {
          @Override
          public String call(ResolvedActivityInfoWrapper input) {
//Get groups by letter
            String label = input.getLabel(getPackageManager());
            if (!TextUtils.isEmpty(label)) {
              String firstChar = label.substring(0, 1);
              if (pattern.matcher(firstChar).matches()) {
                return firstChar.toUpperCase();
              }
            }
            return "#";
          }
        }).subscribe(this); // implementation below
      }

      @Override
      public void onError(Throwable e) {

      }

      @Override
      public void onNext(List<ResolvedActivityInfoWrapper> list) {
        Collections.sort(list, new Comparator<ActivityInfoWrapper>() {
          @Override
// Sort all the apps in the list, not sure it's a good way to do it
          public int compare(ActivityInfoWrapper info1, ActivityInfoWrapper info2) {
            return info1.getLabel(getPackageManager()).compareToIgnoreCase(info2.getLabel(getPackageManager()));
          }
        });
        this.list = list;
      }
    });

一旦我按字母分组,完成后我订阅:

@Override
  public void onCompleted() {
//display the apps
}

  @Override
  public void onError(Throwable e) {

  }

  @Override
  public void onNext(GroupedObservable<String, ResolvedActivityInfoWrapper> input) {
//For each list of apps by letter i subscribe with an observer that will handle those apps (observer code below)
    input.subscribe(new TestObserver(input.getKey()));
  }

观察员:

private class TestObserver implements Observer<ResolvedActivityInfoWrapper> {

    List<ResolvedActivityInfoWrapper> list;
    String letter;

    public TestObserver(String letter) {
      list = new ArrayList<>();
      this.letter = letter;
    }

    @Override
    public void onCompleted() {
      adapter.addData(letter, list);
    }

    @Override
    public void onError(Throwable e) {

    }

    @Override
    public void onNext(ResolvedActivityInfoWrapper input) {
      list.add(input);
    }
}

一切正常,除了一个问题:观察者的 onCompleted 调用顺序不正确。所以我得到了我所有的应用程序,按字母排序,但是这些组的显示顺序不正确(首先是 C,然后是 Y,然后是 M 等)。

我想代码中有很多错误,你能帮我解决这个问题,也许能理解这一切是如何工作的吗?

谢谢

更新: 按照评论部分中的建议(感谢人们),这是我在标准化标签后尝试的内容:

Observable.from(list).groupBy(new Func1<ResolvedActivityInfoWrapper, String>() {
          @Override
          public String call(ResolvedActivityInfoWrapper input) {
            String label = input.getLabel(getPackageManager());
            if (!TextUtils.isEmpty(label)) {
              String firstChar = label.substring(0, 1);
              if (pattern.matcher(firstChar).matches()) {
                return firstChar.toUpperCase();
              }
            }
            return "#";
          }
        })
            .toSortedList(new Func2<GroupedObservable<String, ResolvedActivityInfoWrapper>, GroupedObservable<String, ResolvedActivityInfoWrapper>, Integer>() {
              @Override
              public Integer call(GroupedObservable<String, ResolvedActivityInfoWrapper> obs1, GroupedObservable<String, ResolvedActivityInfoWrapper> obs2) {
                return obs1.getKey().compareToIgnoreCase(obs2.getKey());
              }
            })
            .subscribe(new Observer<List<GroupedObservable<String, ResolvedActivityInfoWrapper>>>() {
              @Override
              public void onCompleted() {

              }

              @Override
              public void onError(Throwable e) {

              }

              @Override
              public void onNext(List<GroupedObservable<String, ResolvedActivityInfoWrapper>> input) {
                String test = input.get(0).getKey();
              }
            });

但它永远不会进入比较功能。

4

0 回答 0