如何同时从2个或更多网站获取数据?(Android应用)

时间:2019-05-07 12:11:37

标签: java android jsoup

我制作了一个应用程序,该应用程序从不同的URL获取数据。我使用for循环使用jsoup lib从不同的URL获取数据。现在,这需要很多时间,例如5秒。 首先从url1中获取数据,然后从2中获取数据,然后从3中获取数据。 这就是我想的时间。

所以我想知道我们是否可以同时(多个线程)从不同的url获取数据?

public  class Title extends AsyncTask <String, Void, Void> {

    String url,ver;
    Bitmap mIcon11 = null;
    ArrayList<App> appsList = new ArrayList<>();

    @Override
    protected Void doInBackground(String ... strings) {
        try {

            for (String string : strings) {
                Document document = Jsoup.connect(string).get();

                Elements a = document.select("div.AppCont");
                Elements b = a.select("article");
                Elements c = b.select("div.ImgDiv");
                Elements d = c.select("img");
                url = d.attr("src");

                InputStream in = new URL(url).openStream();
                mIcon11 = BitmapFactory.decodeStream(in);

                ver = b.get(0).text();
                String z = string.replace("https://a2zapk.com/History/", "");
                z = z.replace("/", "");

                PackageInfo pi = getApplicationContext().getPackageManager().getPackageInfo((z), PackageManager.GET_META_DATA);
                String versionName = pi.versionName;

                ver = ver + " (Installed Version: " +versionName + ")";
                appsList.add(new App(ver, mIcon11));

            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
         add(appsList);
    }

1 个答案:

答案 0 :(得分:2)

您绝对可以,但是管理这些任务的线程会很棘手。我建议使用Rxava为您要从中获取数据的每个站点准备一个单独的可观察对象。然后使用mergemergeDelayError将结果合并到一个Observable中,您可以在主线程上订阅该Observable来更新您的UI。

请查看RxJavaAndroid以获得有关在Android主线程上订阅这些更新的帮助。

您需要熟悉RxJava的4个核心部分:

  1. 您正在做什么-就您而言,这是从服务器中获取数据
  2. 哪个线程池正在运行此任务-我建议使用Schedulers.io(),它是专门为诸如提取数据之类的IO任务预留的池。
  3. 您要在哪个线程池上观察结果-AndroidSchedulers.mainThread()是您想要的
  4. 如何处理结果-更新一些UI等。

使用RxJava(在Kotlin中),看起来类似于以下内容

// What you're doing
Observable.fromCallable {
    listOfApps = parseAppsList(Jsoup.connect("server1.host.com"))
    return@fromCallable listOfApps
}
        // Where you're doing it
        .subscribeOn(Schedulers.io())
        // Where you're observing results
        .observeOn(AndroidSchedulers.mainThread())
        // What you're doing with those results
        .subscribe({ apps ->
            appsList.addAll(apps)
        }, { exception -> 
            // Show an error message
        })

要同时获取多个结果并在每次完成时添加它们,您的代码应如下所示:

val fromServer1 = Observable.fromCallable {
    listOfApps = parseAppsList(Jsoup.connect("server1.host.com"))
    return@fromCallable listOfApps
}
        .subscribeOn(Schedulers.io())


val fromServer2 = Observable.fromCallable {
    listOfApps = parseAppsList(Jsoup.connect("server2.host.com"))
    return@fromCallable listOfApps
}
        .subscribeOn(Schedulers.io())


Observable.merge(fromServer1, fromServer2)
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe({ apps ->
            // Note that this callback will be called once per server
            appsList.addAll(apps)
        }, { exception ->
            // Show an error message
        })