Android新手求助:在Fragment的AsyncTask中用Jsoup提取网页元素
解决你的Jsoup数值提取与Fragment适配问题
嗨,很高兴能帮到你!你的提取思路其实已经找对方向了,不过咱们可以优化几个细节,让代码更稳定,同时适配Fragment的场景:
1. 核心提取逻辑的稳定性优化
你通过document.select("p.testoprezzo").first()定位元素的方法是正确的,p.text()确实能拿到你需要的0.5516。但要注意:如果网页结构变化或者网络请求失败导致找不到这个元素,直接调用p.text()会触发NullPointerException。咱们可以加个空值判断,同时去除文本前后的多余空格:
Element p = document.select("p.testoprezzo").first(); if (p != null) { String priceValue = p.text().trim(); ((Globals) getActivity().getApplication()).setValore(priceValue); } else { ((Globals) getActivity().getApplication()).setValore("获取失败"); }
2. Fragment中findViewById的正确用法
你在Fragment里直接调用findViewById是行不通的,Fragment的视图是在onCreateView中加载的,必须通过getView()获取视图对象后再查找控件,还要确保视图已经创建完成:
@Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); if (getView() != null) { TextView valore = getView().findViewById(R.id.textView4); valore.setText(((Globals) getActivity().getApplication()).getValore()); } }
3. 替代过时的AsyncTask(可选但推荐)
Android API 30之后AsyncTask已经被废弃了,如果你想让代码更符合现代Android开发规范,可以改用ExecutorService+Handler的组合,这样还能避免依赖全局变量传递结果:
// 在Fragment中定义请求方法 private void fetchPrice() { ExecutorService executor = Executors.newSingleThreadExecutor(); Handler handler = new Handler(Looper.getMainLooper()); executor.execute(() -> { // 后台执行网络请求 String priceValue = "获取失败"; try { String url = "https://mywebpage.net/"; Document document = Jsoup.connect(url) .followRedirects(false) .timeout(30000) .get(); Element p = document.select("p.testoprezzo").first(); if (p != null) { priceValue = p.text().trim(); } } catch (Exception e) { e.printStackTrace(); } final String finalPrice = priceValue; handler.post(() -> { // 回到主线程更新UI if (getView() != null) { TextView valore = getView().findViewById(R.id.textView4); valore.setText(finalPrice); } }); }); }
4. 额外注意事项
- 别忘了在
AndroidManifest.xml中添加网络权限:<uses-permission android:name="android.permission.INTERNET" /> - 如果你的
targetSdkVersion >= 28,默认禁止明文HTTP请求,确保你的网页是HTTPS协议,若使用HTTP需要配置网络安全策略。
内容的提问来源于stack exchange,提问作者Il Mago.
相关产品推荐
相关产品推荐

