我将为你详细介绍三种主流方法,从最推荐到最基础的顺序排列:

android 显示html网页源码
(图片来源网络,侵删)
  1. 使用 WebView (最推荐,功能最全)
  2. 使用 TextView (简单直接,适合纯文本)
  3. 使用 AlertDialog (快速预览,不推荐用于复杂源码)

使用 WebView (最推荐)

WebView 是 Android SDK 中专门用于在应用内显示网页内容的控件,它不仅能渲染 HTML,还能执行 JavaScript,功能非常强大,显示源码时,我们只需将源码字符串以 text/plain (纯文本) 的形式传递给它即可。

优点:

  • 功能强大,可以处理高亮、代码折叠等复杂样式。
  • 可以通过 CSS 完美控制源码的显示样式(字体、颜色、行号、语法高亮等)。
  • 是处理任何 HTML 相关任务的标准方式。

缺点:

  • 相比 TextView,设置上稍微复杂一点。

实现步骤:

添加网络权限

android 显示html网页源码
(图片来源网络,侵删)

app/src/main/AndroidManifest.xml 文件中,为你的应用添加互联网访问权限。WebView 需要它来加载网页(获取源码)。

<manifest ...>
    <!-- 添加这一行 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <application ...>
        ...
    </application>
</manifest>

布局文件中添加 WebView

res/layout/activity_main.xml (或其他布局文件) 中添加一个 WebView 控件。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <Button
        android:id="@+id/btn_load_source"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="加载网页源码" />
    <WebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

在 Activity 或 Fragment 中编写逻辑

android 显示html网页源码
(图片来源网络,侵删)

这是核心部分,我们将使用 Jsoup 库来高效、安全地从 URL 获取 HTML 源码,然后通过 WebView 显示。

a. 添加 Jsoup 依赖

app/build.gradle 文件的 dependencies 代码块中添加:

dependencies {
    // ... 其他依赖
    implementation 'org.jsoup:jsoup:1.17.2' // 使用最新版本
}

同步你的项目。

b. 编写 Java/Kotlin 代码

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.Button
import org.jsoup.Jsoup
class MainActivity : AppCompatActivity() {
    private lateinit var webView: WebView
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        webView = findViewById(R.id.webview)
        val loadButton: Button = findViewById(R.id.btn_load_source)
        // 必须设置,否则在 Android 9 (API 28) 及以上版本无法加载 HTTP (非 HTTPS) 的 URL
        webView.settings.javaScriptEnabled = true
        // 点击按钮时执行加载操作
        loadButton.setOnClickListener {
            // 示例:获取一个网页的源码
            // 注意:请在子线程中执行网络请求,避免阻塞主线程导致 ANR
            // 这里为了简化,直接调用,实际开发中请使用协程、AsyncTask 或其他异步方式
            loadHtmlSource("https://www.baidu.com")
        }
    }
    private fun loadHtmlSource(url: String) {
        try {
            // Jsoup 在子线程中执行网络请求
            val doc = Jsoup.connect(url).get()
            val htmlSource = doc.html()
            // 在主线程更新 UI
            runOnUiThread {
                // 关键:使用 loadDataWithBaseURL 来加载纯文本
                // baseUrl: 可以是 null 或一个空字符串
                // data: 要加载的源码字符串
                // mimeType: "text/plain" 表示我们加载的是纯文本
                // encoding: 字符编码,通常是 "UTF-8"
                // historyUrl: null
                webView.loadDataWithBaseURL(null, htmlSource, "text/plain", "UTF-8", null)
            }
        } catch (e: Exception) {
            e.printStackTrace()
            // 可以在这里处理错误,比如显示一个 Toast
            runOnUiThread {
                webView.loadData("加载失败: ${e.message}", "text/plain", "UTF-8")
            }
        }
    }
    // 处理返回键,让 WebView 能够返回历史页面
    override fun onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack()
        } else {
            super.onBackPressed()
        }
    }
}

代码解释:

  • Jsoup.connect(url).get(): 这是 Jsoup 库发起网络请求并获取整个 HTML 文档内容的方法,它非常方便且能防止一些基本的网页攻击。
  • runOnUiThread: 网络请求不能在主线程(UI 线程)中执行,否则会抛出 NetworkOnMainThreadException,获取到源码后,必须切回主线程才能更新 WebView 的内容。
  • webView.loadDataWithBaseURL(...): 这是 WebView 的核心方法。
    • 我们将 mimeType 设置为 "text/plain",告诉 WebView 不要尝试渲染 HTML,而是将其作为纯文本显示。
    • 这样,WebView 就会像文本编辑器一样展示源码,包括 <, >, 等标签。

使用 TextView (简单直接)

如果你的需求非常简单,只是想把源码字符串原封不动地显示出来,TextView 是一个更轻量级的选择。

优点:

  • 非常简单,几行代码就能搞定。
  • 性能开销比 WebView 小。

缺点:

  • 功能非常有限,无法进行语法高亮、滚动等复杂操作。
  • 对于很长的源码,TextView 的性能可能不如 WebView 优化得好。

实现步骤:

布局文件中添加 TextView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <Button
        android:id="@+id/btn_load_source"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="加载到TextView" />
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/source_text_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fontFamily="monospace" <!-- 使用等宽字体,看起来更像代码 -->
            android:textColor="@android:color/black"
            android:background="@android:color/white" />
    </ScrollView>
</LinearLayout>

在 Activity 或 Fragment 中编写逻辑

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import org.jsoup.Jsoup
class MainActivity : AppCompatActivity() {
    private lateinit var sourceTextView: TextView
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main_textview) // 使用包含 TextView 的布局
        sourceTextView = findViewById(R.id.source_text_view)
        val loadButton: Button = findViewById(R.id.btn_load_source)
        loadButton.setOnClickListener {
            loadHtmlSourceToTextView("https://www.github.com")
        }
    }
    private fun loadHtmlSourceToTextView(url: String) {
        try {
            val doc = Jsoup.connect(url).get()
            val htmlSource = doc.html()
            // 直接设置文本内容
            sourceTextView.text = htmlSource
        } catch (e: Exception) {
            e.printStackTrace()
            sourceTextView.text = "加载失败: ${e.message}"
        }
    }
}

注意:同样,网络请求应放在子线程中执行,此示例为简化代码省略了。


使用 AlertDialog (快速预览)

如果你只是想在用户点击一个按钮后,弹出一个对话框快速看一下源码,而不是长期显示在界面上,这个方法很合适。

优点:

  • 实现快速,代码量少。
  • 不需要额外的布局文件。

缺点:

  • 极不推荐用于显示长源码,因为对话框空间有限,用户体验很差。
  • 功能单一,无法滚动或进行其他交互。

实现步骤:

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AlertDialog
import org.jsoup.Jsoup
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main) // 使用包含 Button 的布局
        val showInDialogButton: Button = findViewById(R.id.btn_load_source)
        showInDialogButton.setOnClickListener {
            showSourceInDialog("https://www.android.com")
        }
    }
    private fun showSourceInDialog(url: String) {
        try {
            val doc = Jsoup.connect(url).get()
            val htmlSource = doc.html()
            AlertDialog.Builder(this)
                .setTitle("网页源码")
                .setMessage(htmlSource) // 直接设置源码为消息内容
                .setPositiveButton("确定", null)
                .show()
        } catch (e: Exception) {
            e.printStackTrace()
            AlertDialog.Builder(this)
                .setTitle("错误")
                .setMessage("加载失败: ${e.message}")
                .setPositiveButton("确定", null)
                .show()
        }
    }
}

总结与选择建议

特性 WebView TextView AlertDialog
易用性 中等 简单 简单
功能丰富度 极高 (可定制样式、高亮等) 极低
性能 良好 (针对复杂内容优化) 一般 (长文本可能卡顿) 不适用
适用场景 显示完整源码、代码查看器、需要高亮等 简单文本显示、源码预览 快速、临时的源码弹窗

最终建议:

  • 如果你想做一个功能完善的代码查看器或需要优雅地显示源码,请选择 WebView,这是最专业、最灵活的方案。
  • 如果你只是想在界面上某个地方简单展示一小段 HTML 片段的源码,可以选择 TextView
  • 如果你只是想让用户点击一下,弹窗看一眼源码就完事,可以使用 AlertDialog,但要警告用户源码可能很长。