Android Studio新手求助:Jsoup解析网页崩溃,需实现奥林巴斯相机图片下载自动化
问题解决步骤
1. 修复网络请求崩溃问题
Android 禁止在主线程执行网络操作,你的getHTML方法直接在主线程调用Jsoup的同步网络请求,会抛出NetworkOnMainThreadException导致崩溃。必须把网络请求放到子线程中执行:
方案1:使用AsyncTask(适合新手快速实现)
public class HTMLParser { public interface OnHtmlLoadedListener { void onHtmlLoaded(String html); void onError(); } public void getHTML(String url, OnHtmlLoadedListener listener) { new AsyncTask<String, Void, String>() { @Override protected String doInBackground(String... strings) { try { Document doc = Jsoup.connect(strings[0]).get(); return doc.html(); } catch (Exception e) { e.printStackTrace(); return null; } } @Override protected void onPostExecute(String html) { if (html != null) { listener.onHtmlLoaded(html); } else { listener.onError(); } } }.execute(url); } }
调用方式:
new HTMLParser().getHTML("https://www.oishare/DCIM/100OLYMP/", new HTMLParser.OnHtmlLoadedListener() { @Override public void onHtmlLoaded(String html) { // 在这里处理获取到的HTML } @Override public void onError() { // 处理错误,比如提示用户网络问题 } });
方案2:使用Coroutine(更现代的方式)
如果你的项目支持Coroutine,可使用该方案:
// 先在build.gradle添加Coroutine依赖 // implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3" public class HTMLParser { private CoroutineScope scope = CoroutineScope(Dispatchers.IO); public void getHTML(String url, Consumer<String> onSuccess, Runnable onError) { scope.launch { try { Document doc = Jsoup.connect(url).get(); String html = doc.html(); withContext(Dispatchers.Main) { onSuccess.accept(html); } } catch (Exception e) { e.printStackTrace(); withContext(Dispatchers.Main) { onError.run(); } } } } }
2. 实现HTML链接替换
获取到HTML后,可通过两种方式完成链接替换:
方式1:直接字符串替换
String modifiedHtml = html.replace("http://oishare/DCIM/100OLYMP/FILE.html?/DCIM/100OLYMP/", "http://oishare/DCIM/100OLYMP/");
方式2:用Jsoup操作DOM(更可靠,避免误匹配)
如果链接在<a>标签的href属性中,可直接修改DOM元素:
Document doc = Jsoup.parse(html); Elements links = doc.select("a[href*=FILE.html?/DCIM/100OLYMP/]"); for (Element link : links) { String oldHref = link.attr("href"); String newHref = oldHref.replace("FILE.html?/DCIM/100OLYMP/", ""); link.attr("href", newHref); } String modifiedHtml = doc.html();
3. 在WebView中加载修改后的HTML
使用loadDataWithBaseURL方法加载,确保页面相对链接能正确指向相机Wi-Fi服务器:
WebView webView = findViewById(R.id.webview); webView.getSettings().setJavaScriptEnabled(true); // 按需启用JS支持 webView.loadDataWithBaseURL("http://oishare/DCIM/100OLYMP/", modifiedHtml, "text/html", "UTF-8", null);
4. 自动化下载RAW图片的思路
无需通过WebView,直接解析页面链接批量下载即可:
- 用Jsoup解析页面,筛选出RAW图片链接(比如后缀为
.ORF的文件) - 为每个链接启动子线程执行下载任务
- 将文件保存到本地存储(Android 6.0+需动态申请存储权限,Android 10+建议用Scoped Storage或MediaStore)
示例代码片段:
// 解析图片链接 Document doc = Jsoup.connect("https://www.oishare/DCIM/100OLYMP/").get(); Elements imageLinks = doc.select("a[href$=.ORF]"); // 匹配ORF后缀的链接 for (Element link : imageLinks) { String imageUrl = link.attr("abs:href"); // 获取绝对URL downloadImage(imageUrl); } // 下载方法示例 private void downloadImage(String url) { new AsyncTask<String, Void, Boolean>() { @Override protected Boolean doInBackground(String... strings) { try { URL imageUrl = new URL(strings[0]); HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection(); conn.connect(); InputStream inputStream = conn.getInputStream(); // 保存到DCIM目录 File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), new File(strings[0]).getName()); FileOutputStream outputStream = new FileOutputStream(file); byte[] buffer = new byte[1024]; int len; while ((len = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, len); } outputStream.close(); inputStream.close(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } @Override protected void onPostExecute(Boolean success) { if (success) { // 下载成功提示 } else { // 下载失败提示 } } }.execute(url); }
额外注意事项
- 网络权限:在
AndroidManifest.xml中添加<uses-permission android:name="android.permission.INTERNET" /> - 文件权限:Android 6.0+需动态申请存储权限,Android 10+优先使用Scoped Storage或MediaStore保存文件
- 相机Wi-Fi连接:引导用户手动连接相机Wi-Fi,或添加网络检测逻辑
内容的提问来源于stack exchange,提问作者laguro
相关产品推荐
相关产品推荐

