增强型WebView组件,重新封装

* 增强型WebView组件(兼容Android 4.4+)
* 特性:
* 1. 全生命周期管理
* 2. 智能硬件加速
* 3. 链式配置API
* 4. 安全下载管理
* 5. 全屏视频支持
*
*
* 说明:
* ⑴ 智能加速方案:
*      ● API 21+:启用硬件加速层+渲染进程优化
*      ● API <21:软件加速+缓存优化
*      ● 自动异常回退机制
* ⑵生命周期管理:
*      ● 使用Application全局回调
*      ● 自动解除注册
*      ● 双重资源释放保障
* ⑶全屏处理增强:
*      ● 横竖屏自动切换
*      ● 视图层级安全处理
*      ● 支持JS控制全屏状态
* ⑷下载管理:
*      ● 动态权限申请
*      ● 系统下载管理器集成
*      ● 下载进度通知
* ⑸兼容性处理:
*      ● 支持Android 4.4+
*      ● 自动处理混合内容
*      ● 内存泄漏防护


封装的类的设计具有以下核心逻辑和优点:

核心逻辑分析


1. 继承体系 :
public class CustSupportFullWebView extends WebView {
    // 继承Android原生WebView基础功能
}
2. 功能模块划分 :
  •  全屏视频处理(通过 `FullScreenChromeClient` 实现)

  • 下载管理(通过 `FileDownloadListener` 实现)

  • 生命周期管理(通过Activity生命周期绑定)

  •  视频控制接口(通过 `VideoControlInterface` 实现)

架构优点

1. 模块化设计 :
// 各功能通过内部类实现,高内聚低耦合
private class FullScreenChromeClient extends WebChromeClient { ... }
private class FileDownloadListener implements DownloadListener { ... }
2. 兼容性处理 :

自动检测API级别选择加速方案
 

public CustSupportFullWebView autoEnableHardwareAccel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        enableHardwareAccel();  // API 21+使用硬件加速
    } else {
        enableSoftwareAccel();  // 低版本回退方案
    }
    return this;
}
3. 链式调用设计 :
// 配置示例
new CustSupportFullWebView(context)
    .configureWebSettings()
    .autoEnableHardwareAccel()
    .setDownloadHandler();
4.生命周期管理增强
1)双重销毁保障
private void releaseResources() {
    // 1. 先移除父视图
    if (getParent() instanceof ViewGroup) {
        ((ViewGroup)getParent()).removeView(this);
    }
    // 2. 检查窗口附着状态
    if (mIsAttachedToWindow) {
        onDetachedFromWindow(); 
    }
    // 3. 最后执行原生销毁
    super.destroy();
}
2)全局生命周期监听 :
activity.getApplication().registerActivityLifecycleCallbacks(
    new Application.ActivityLifecycleCallbacks() {
        @Override
        public void onActivityDestroyed(Activity activity) {
            if (activity == mHostActivity) {
                releaseResources();
            }
        }
        // ... 其他生命周期方法 ...
    }
);

性能优化点


1. 智能加速策略 :
  • 硬件加速(API 21+)

  • 软件加速(兼容方案)

  • 自动异常回退机制


2. 资源管理 :
 
private void releaseResources() {
    // 1. 先移除视图
    if (getParent() instanceof ViewGroup) {
        ((ViewGroup) getParent()).removeView(this);
    }
    // 2. 再执行销毁
    super.destroy();
}

扩展性设计亮点


1. 代理模式应用 :
private static class WebViewClientProxy extends WebViewClient {
    // 合并外部和内部处理逻辑
}
2. 监听器接口 :
public interface FullscreenListener {
    void onEnterFullscreen(Uri videoUri);
    void onExitFullscreen();
}

3.JS桥接接口 :
@JavascriptInterface
public void onFullscreenVideo(final String src) {
    mHostActivity.runOnUiThread(() -> {
        if (mFullscreenListener != null) {
            mFullscreenListener.onEnterFullscreen(Uri.parse(src));
        }
    });
}
4. DOM动态监听 :
 
new MutationObserver(mutations => {
    mutations.forEach(mu => {
        mu.addedNodes.forEach(node => {
            if(node.nodeName === 'VIDEO') {
                node.style.zIndex = 9999;
                node.addEventListener('click', handleVideoClick);
            }
        });
    });
}).observe(document.body, {childList: true, subtree: true});

该实现通过分层设计将复杂功能模块化,同时保持各模块间的低耦合度,是Android WebView定制开发的优秀实践。该设计同时也完美平衡了功能完整性和性能要求,通过模块化架构和兼容性处理,适用于复杂的WebView应用场景。

完整代码:

直接上代码:

public class CustSupportFullWebView extends WebView {

    // 模块 成员变量
    public Activity mHostActivity;
    private View mFullscreenView;
    private WebChromeClient.CustomViewCallback mFullscreenCallback;
    private List<Uri> mVideoUris = new ArrayList<>();  //todo 页面视频地址(目前还未取到值)
    // 暂存全屏播放前原始方向
    private int mOriginalOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
    // 记录全屏播放前滚动位置记录
    private int mOriginalScrollX, mOriginalScrollY;  // 保存进入全屏前的滚
    /**
     * 是否支持根据视频宽高自适应横屏竖屏选择。 默认不支持false
     */
    private boolean supportChooseScreenWithWidthHeight = false;
    private boolean mIsDestroyed = false;  // 销毁状态标记
    private boolean mIsAttachedToWindow = false; // 新增窗口附着状态
    // end模块

    // WebChromeClient代理
    private FullScreenChromeClient mInternalChromeClient = new FullScreenChromeClient();

    // 模块 构造函数
    public CustSupportFullWebView(Context context) {
        super(context);
        init((Activity) context);
    }

    public CustSupportFullWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init((Activity) context);
    }

    public CustSupportFullWebView(@NonNull Context context, @NonNull Activity hostActivity) {
        super(context);
        init(hostActivity);
    }
    // end模块

    // 模块 初始化方法
    @SuppressLint("SetJavaScriptEnabled")
    public void init(Activity hostActivity) {
        this.mHostActivity = hostActivity;

        // 链式配置
        configureWebSettings()
                .appendUserAgentString("customApp") // 默认添加 customApp到UserAgent方便打开网页是H5获取值判断是不是customApp打开
                .setChromeClient()
                .setDownloadHandler()
                .autoEnableHardwareAccel()  // 自动选择加速方案
                .injectStateObserver()
                .setCustomWebClient();

        // 绑定生命周期
        bindActivityLifecycle(hostActivity);
    }
    // end模块

    // 模块 链式配置方法
    /**
     * 基础配置入口(必须首先调用)
     */
    public CustSupportFullWebView configureWebSettings() {
        WebSettings settings = getSettings();
        settings.setJavaScriptEnabled(true); //设置WebView属性,运行执行js脚本
        settings.setDomStorageEnabled(true); //DOM Storage  // 开启DOM缓存,开启LocalStorage存储(html5的本地存储方式)
        settings.setMediaPlaybackRequiresUserGesture(false);
        settings.setUseWideViewPort(true);
        settings.setLoadWithOverviewMode(true);

        // 确认字体文件路径和权限设置
        settings.setAllowFileAccess(true); // 是否可访问Content Provider的资源,默认值 true
        settings.setAllowContentAccess(true); // 是否可访问本地文件,默认值 true
        // 如果网页内容来自网络,可能需要额外设置:
        settings.setAllowFileAccessFromFileURLs(true);
        settings.setAllowUniversalAccessFromFileURLs(true);

        //针对 Android 5.8+ 需要额外配置
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            settings.setMixedContentMode(
                    WebSettings.MIXED_CONTENT_ALWAYS_ALLOW // 允许混合内容
            );
        }
        return this;
    }

    /**
     * <p>
     * Description: [UserAgent里追加字符串]
     * <p>
     *
     *
     * @param appendStr
     *
     * @return CustSupportFullWebView
     *
     * ${tags}
     */
    public CustSupportFullWebView appendUserAgentString(String appendStr) {
        String originalUserAgent = getSettings().getUserAgentString();
        String newUserAgent;

        if(StringUtils.isBlank(originalUserAgent)) {
            newUserAgent = appendStr;
        } else {
            newUserAgent = originalUserAgent + " " + appendStr;
        }

        getSettings().setUserAgentString(newUserAgent);
        return this;
    }

    public boolean isSupportChooseScreenWithWidthHeight() {
        return supportChooseScreenWithWidthHeight;
    }

    public void setSupportChooseScreenWithWidthHeight(boolean supportChooseScreenWithWidthHeight) {
        this.supportChooseScreenWithWidthHeight = supportChooseScreenWithWidthHeight;
    }

    /**
     * 设置缓存模式
     * @param mode WebSettings.LOAD_* 常量
     */
    public CustSupportFullWebView setCacheMode(int mode) {
        getSettings().setCacheMode(mode);
        return this;
    }

    /**
     * 设置自定义Chrome客户端(全屏处理)
     */
    public CustSupportFullWebView setChromeClient() {
        setWebChromeClient(new ChromeClientProxy(null, mInternalChromeClient));
        return this;
    }

    /**
     * 设置文件下载处理器
     */
    public CustSupportFullWebView setDownloadHandler() {
        setDownloadListener(new FileDownloadListener(null));
        return this;
    }

    /**
     * 做修改,若用户已自定义实现了则采用自定义的,否则采用此处默认的通知显示下载
     * @param listener
     */
    @Override
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值