android加载H5网页

# Android原生WebView加载线上H5完整教程(Java)
## 一、核心前提:清单文件配置 AndroidManifest.xml
### 1. 网络权限(加载线上网页必须)
```xml
<!-- 访问互联网必备 -->
<uses-permission android:name="android.permission.INTERNET"/>
```
### 2. 允许HTTP明文(仅测试环境,线上建议只用HTTPS)
在`<application>`标签内添加属性:
```xml
android:usesCleartextTraffic="true"
```
> Android 9(API28)及以上系统默认禁止加载 `http://` 地址,HTTPS无需该配置。

## 二、布局文件(activity_web.xml)
用FrameLayout作为容器,**不直接写WebView标签**,动态创建避免内存泄漏
```xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 顶部加载进度条 -->
    <ProgressBar
        android:id="@+id/progress_bar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="3dp"
        android:visibility="gone"/>
</FrameLayout>
```

## 三、Activity 完整代码(加载线上H5)
```java
import android.os.Build;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import androidx.appcompat.app.AppCompatActivity;

public class WebActivity extends AppCompatActivity {
    private FrameLayout rootLayout;
    private ProgressBar progressBar;
    private WebView webView;
    // 替换为你的线上H5地址,必须 https
    private final String H5_URL = "https://tickets.plaindesign.cn/trwh";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web);
        rootLayout = findViewById(R.id.root_layout);
        progressBar = findViewById(R.id.progress_bar);

        // 1. 动态创建WebView
        webView = new WebView(getApplicationContext());
        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT
        );
        webView.setLayoutParams(layoutParams);
        rootLayout.addView(webView);

        // 2. 初始化WebView配置(线上H5必开参数)
        initWebSetting();

        // 3. 网页监听客户端
        webView.setWebViewClient(new MyWebClient());
        webView.setWebChromeClient(new MyChromeClient());

        // 4. 核心方法:加载线上H5链接
        webView.loadUrl(H5_URL);
    }

    /** WebView基础配置 */
    private void initWebSetting() {
        WebSettings settings = webView.getSettings();
        // 开启JS支持(大部分H5页面依赖JS)
        settings.setJavaScriptEnabled(true);
        // 适配手机屏幕
        settings.setUseWideViewPort(true);
        settings.setLoadWithOverviewMode(true);
        // 缓存策略,优先缓存,网络差时使用缓存
        settings.setCacheMode(WebSettings.LOAD_DEFAULT);
        // 禁止系统字体缩放打乱H5页面布局
        settings.setTextZoom(100);

        // API21+ 支持页面同时混合加载http/https资源
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
    }

    /** 页面跳转拦截器:所有链接在当前WebView打开,不跳转手机浏览器 */
    class MyWebClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    }

    /** 监听页面加载进度、弹窗、文件上传 */
    class MyChromeClient extends WebChromeClient {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
            if (newProgress == 100) {
                progressBar.setVisibility(android.view.View.GONE);
            } else {
                progressBar.setVisibility(android.view.View.VISIBLE);
                progressBar.setProgress(newProgress);
            }
        }
    }

    // 返回键逻辑:网页后退,而不是直接关闭页面
    @Override
    public void onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack();
        } else {
            super.onBackPressed();
        }
    }

    // 页面销毁,彻底释放WebView,解决内存泄漏
    @Override
    protected void onDestroy() {
        if (webView != null) {
            webView.loadUrl("about:blank");
            webView.clearHistory();
            ((ViewGroup) webView.getParent()).removeView(webView);
            webView.destroy();
            webView = null;
        }
        super.onDestroy();
    }
}
```

## 四、关键补充功能(业务常用)
### 1. H5 和 Android 双向JS交互
#### 1)安卓提供方法给H5调用
新增交互桥梁类,在`onCreate`中绑定:
```java
// 绑定JS桥梁,H5通过 window.appBridge 调用
webView.addJavascriptInterface(new JsBridge(), "appBridge");

// 交互类
public class JsBridge {
    // 必须加 @JavascriptInterface 注解,高版本WebView安全限制
    @JavascriptInterface
    public String getLoginToken() {
        // 返回App本地存储的登录token给H5
        return "xxxx-user-token-2026";
    }
}
```
H5页面JS调用:
```javascript
let token = window.appBridge.getLoginToken();
console.log("App token:", token);
```

#### 2)Android主动调用H5的JS方法
页面加载完成后执行:
```java
webView.evaluateJavascript("h5Init()", result -> {
    // result 是JS函数返回值
});
```

## 五、常见问题排查
1. **页面空白/无法访问线上地址**
   - 漏加 `INTERNET` 网络权限;
   - URL是http,Android9以上未配置 `usesCleartextTraffic`;
   - 服务器限制IP、域名防盗链拦截WebView请求。

2. H5页面JS失效
   - 忘记开启 `setJavaScriptEnabled(true)`;

3. 返回键直接关闭页面,无法回退网页
   - 未重写`onBackPressed()`回退逻辑;

4. 页面退出后内存泄漏
   - 必须动态创建WebView,销毁时执行完整destroy释放代码;

## 六、生产环境优化方案
系统WebView不同手机内核差异巨大,存在二维码识别、文件上传、视频播放兼容问题,企业项目推荐**腾讯X5 WebView**,API和原生WebView完全一致,兼容性大幅提升。

 

posted @ 2026-07-29 22:59  热心市民~菜先生  阅读(53)  评论(0)    收藏  举报