获取 HTML 字符串(最常见)
这是最基础的需求,比如你需要获取一个网页的 HTML 内容,然后从中解析出特定的信息(如标题、链接、价格等),这通常使用 HTTP 客户端 来完成。

在 Android 中,主要有两种主流的 HTTP 客户端库:
- OkHttp (强烈推荐): Android 开发的事实标准,由 Square 公司开发,性能优秀、API 简洁、功能强大。
- HttpURLConnection (原生 API): Java 标准库自带的,无需额外依赖,但 API 相对繁琐,功能也较少。
下面我们重点介绍 OkHttp 的使用方法。
步骤 1: 添加 OkHttp 依赖
在你的 app/build.gradle 文件中添加依赖:
dependencies {
implementation("com.squareup.okhttp3:okhttp:4.12.0") // 使用最新版本
}
步骤 2: 添加网络权限
在 app/src/main/AndroidManifest.xml 文件中添加网络访问权限:

<manifest ...>
<!-- 必须添加的权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<application ...>
...
</application>
</manifest>
步骤 3: 编写代码获取 HTML
由于网络请求不能在主线程(UI 线程)中执行,否则会抛出 NetworkOnMainThreadException 异常,我们有以下几种方式来处理异步请求:
方式 A: 使用 OkHttp 的 Callback (传统回调方式)
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
private OkHttpClient client;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
client = new OkHttpClient();
findViewById(R.id.button_fetch).setOnClickListener(v -> fetchHtml());
}
private void fetchHtml() {
String url = "https://www.example.com"; // 替换成你的服务器地址
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// 请求失败,在主线程更新UI
runOnUiThread(() -> Toast.makeText(MainActivity.this, "请求失败: " + e.getMessage(), Toast.LENGTH_SHORT).show());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
// 请求成功
if (response.isSuccessful()) {
final String htmlString = response.body().string();
// 注意:response.body().string() 只能被调用一次!
// 如果需要多次使用,请先将其保存起来。
// 在主线程更新UI
runOnUiThread(() -> {
// 将HTML显示在TextView中(对于长文本,建议使用ScrollView包裹的TextView)
TextView tvResult = findViewById(R.id.tv_result);
tvResult.setText(htmlString);
Toast.makeText(MainActivity.this, "获取成功!", Toast.LENGTH_SHORT).show();
});
} else {
runOnUiThread(() -> Toast.makeText(MainActivity.this, "服务器返回错误: " + response.code(), Toast.LENGTH_SHORT).show());
}
}
});
}
}
方式 B: 使用 Kotlin Coroutines (更现代、推荐的方式)
如果你使用 Kotlin,结合协程可以让代码更简洁优雅。

在 build.gradle 中添加协程依赖:
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3") // 使用最新版本
}
在 Activity 中使用:
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import android.widget.Toast
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
class MainActivityKt : AppCompatActivity() {
private val client = OkHttpClient()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<TextView>(R.id.button_fetch).setOnClickListener {
fetchHtmlWithCoroutines()
}
}
private fun fetchHtmlWithCoroutines() {
val url = "https://www.example.com"
// GlobalScope.launch 启动一个协程
GlobalScope.launch(Dispatchers.Main) { // 在主线程执行UI更新
try {
// withContext(Dispatchers.IO) 将代码块切换到IO线程执行网络请求
val htmlString = withContext(Dispatchers.IO) {
val request = Request.Builder()
.url(url)
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw Exception("Unexpected code $response")
response.body!!.string()
}
}
// 回到主线程更新UI
findViewById<TextView>(R.id.tv_result).text = htmlString
Toast.makeText(this@MainActivityKt, "获取成功!", Toast.LENGTH_SHORT).show()
} catch (e: Exception) {
Toast.makeText(this@MainActivityKt, "请求失败: ${e.message}", Toast.LENGTH_SHORT).show()
}
}
}
}
加载并显示完整的网页(WebView)
如果你的需求不是解析 HTML,而是想在 App 内直接显示一个完整的网页,那么使用 WebView 是最佳选择。
步骤 1: 添加 WebView 依赖和权限
确保 AndroidManifest.xml 中有网络权限。
步骤 2: 在布局文件中添加 WebView
<!-- res/layout/activity_main.xml -->
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
步骤 3: 在 Activity 中加载网页
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class WebViewActivity extends AppCompatActivity {
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webview);
// 启用 JavaScript (如果网页需要)
webView.getSettings().setJavaScriptEnabled(true);
// 设置 WebViewClient,这样点击链接时会在当前 WebView 中打开,而不是跳转到浏览器
webView.setWebViewClient(new WebViewClient());
// 加载网页
webView.loadUrl("https://www.google.com");
}
// 处理返回键,让 WebView 能够返回上一页
@Override
public void onBackPressed() {
if (webView.canGoBack()) {
webView.goBack();
} else {
super.onBackPressed();
}
}
}
解析 HTML (抓取数据)
获取到 HTML 字符串后,通常需要从中提取有用的信息,手动用字符串处理(如 indexOf, substring)非常脆弱,推荐使用 JSoup 这个专门为 HTML 设计的解析库。
步骤 1: 添加 JSoup 依赖
在 app/build.gradle 中添加:
dependencies {
implementation("org.jsoup:jsoup:1.17.2") // 使用最新版本
}
步骤 2: 使用 JSoup 解析 HTML
结合上面的 OkHttp 示例,我们在获取到 HTML 字符串后进行解析。
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
// ... 在 OkHttp 的 onResponse 回调中 ...
if (response.isSuccessful()) {
final String htmlString = response.body().string();
runOnUiThread(() -> {
// 使用 JSoup 解析
Document doc = Jsoup.parse(htmlString);
// 示例1: 获取<title>标签里的内容
String title = doc.title();
Log.d("JSoup", "网页标题: " + title);
// 示例2: 获取所有<a>标签
Elements links = doc.select("a[href]");
Log.d("JSoup", "所有链接数量: " + links.size());
for (Element link : links) {
Log.d("JSoup", "链接: " + link.attr("href") + " - 文本: " + link.text());
}
// 示例3: 获取class为"my-class"的div
Elements divs = doc.select("div.my-class");
for (Element div : divs) {
Log.d("JSoup", "找到的div内容: " + div.text());
}
// 示例4: 获取ID为"main-content"的元素
Element mainContent = doc.getElementById("main-content");
if (mainContent != null) {
Log.d("JSoup", "主要内容: " + mainContent.text());
}
});
}
总结与对比
| 方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| OkHttp | 获取 HTML 字符串 | 性能高,API 简洁。 支持异步请求,不阻塞 UI。 生态强大,可扩展性好。 |
本身不提供解析功能,需配合其他库。 |
| WebView | 完整显示网页 | 无需自己处理 HTML/CSS/JS。 用户体验与原生 App 内嵌网页一致。 |
占用内存较大。 安全性需注意(防止 XSS 攻击)。 与原生交互相对复杂。 |
| JSoup | 解析 HTML | 专为 HTML 设计,非常强大和灵活。 支持类似 CSS 的选择器,方便定位元素。 容错性好,能处理不规范的 HTML。 |
只能解析静态 HTML,无法执行 JavaScript 来获取动态加载的内容。 |
重要注意事项
- 网络线程: 绝对不要在主线程中进行网络请求。
- HTTPS: 现代服务器普遍使用 HTTPS,如果你的服务器是自签名的证书,需要在 OkHttp 中配置信任所有证书(仅用于开发或测试环境,生产环境非常危险!)。
- 超时设置: 建议为 OkHttp 请求设置连接、读取和写入超时,防止应用因网络问题而卡死。
OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .build(); - : 很多现代网页使用 JavaScript 动态加载内容,使用 OkHttp + JSoup 只能获取到初始的 HTML,无法获取 JS 动态生成的内容,这种情况下,你可能需要使用 Selenium 或 Playwright 等工具在服务器端模拟浏览器进行抓取,然后将结果通过 API 提供给 App。
希望这份详细的指南能帮助你解决 Android 访问服务器 HTML 的问题!
