我做了一个应用程序,它从不同的网址获取数据.我使用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);
}
最佳答案
您绝对可以,但是管理这些任务的线程可能会很棘手.我建议使用Rxava为您要从中获取数据的每个站点准备一个单独的可观察对象.然后使用merge或mergeDelayError将结果合并到单个Observable中,您可以在主线程上订阅该Observable来更新UI.
请查看RxJavaAndroid,以获取有关在Android主线程上订阅这些更新的帮助.
您需要熟悉RxJava的4个核心部分:
>您正在做什么-就您而言,这是从服务器获取数据
>哪个线程池正在运行此任务-我建议使用Schedulers.io(),它是专门为IO任务(例如,获取数据)预留的池.
>您要在哪个线程池上观察结果-AndroidSchedulers.mainThread()是您想要的结果
>如何处理结果-更新某些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
})