5分钟上手AgentWeb:Android开发者必备WebView框架
为什么选择AgentWeb?
你是否还在为Android WebView的各种兼容性问题头疼?从基础的页面加载、进度条显示,到复杂的文件上传下载、JS交互,再到安全性配置和生命周期管理,WebView的坑总是层出不穷。AgentWeb作为一款基于Android WebView的增强框架,通过封装常用功能和提供灵活扩展,让开发者能在5分钟内实现企业级WebView应用。本文将从快速集成到高级定制,带你掌握AgentWeb的核心用法。
读完本文你将获得:
- 3行代码实现WebView基础功能
- 完整的文件上传下载解决方案
- JS与Native双向通信最佳实践
- 自定义WebView设置与生命周期管理
- 常见问题的解决方案与性能优化技巧
架构概览
AgentWeb采用分层设计,核心层提供基础WebView能力,中间层处理业务逻辑,上层通过Builder模式暴露API。其主要组件包括:
快速集成
1. 添加依赖
在项目根目录的build.gradle中添加仓库:
allprojects {
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
在模块build.gradle中添加依赖:
// AndroidX版本
implementation 'io.github.justson:agentweb-core:v5.1.1-androidx'
implementation 'io.github.justson:agentweb-filechooser:v5.1.1-androidx' // 文件选择器(可选)
implementation 'com.github.Justson:Downloader:v5.0.4-androidx' // 下载器(可选)
2. 基础使用(3行核心代码)
在Activity中添加WebView容器布局(activity_web.xml):
<?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">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"/>
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
在Activity中初始化AgentWeb:
public class WebActivity extends AppCompatActivity {
private AgentWeb mAgentWeb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web);
// 核心初始化代码
mAgentWeb = AgentWeb.with(this)
.setAgentWebParent((ViewGroup) findViewById(R.id.container), new FrameLayout.LayoutParams(-1, -1))
.useDefaultIndicator(Color.RED, 3) // 使用默认进度条
.createAgentWeb()
.ready()
.go("https://www.baidu.com");
}
@Override
protected void onPause() {
mAgentWeb.getWebLifeCycle().onPause();
super.onPause();
}
@Override
protected void onResume() {
mAgentWeb.getWebLifeCycle().onResume();
super.onResume();
}
@Override
protected void onDestroy() {
mAgentWeb.getWebLifeCycle().onDestroy();
super.onDestroy();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// 处理返回键事件
return mAgentWeb.handleKeyEvent(keyCode, event) || super.onKeyDown(keyCode, event);
}
}
核心功能详解
进度条定制
AgentWeb提供默认进度条,也支持完全自定义:
// 默认进度条
.useDefaultIndicator(int color, int height)
// 自定义进度条
.setIndicator(new CommonIndicator(this))
// 自定义指示器实现类
public class CommonIndicator extends BaseIndicatorView {
@Override
public View getView() {
View view = LayoutInflater.from(getContext()).inflate(R.layout.indicator_view, null);
mProgressBar = view.findViewById(R.id.progress);
return view;
}
@Override
public void setProgress(int newProgress) {
mProgressBar.setProgress(newProgress);
if (newProgress == 100) {
postDelayed(mDismissRunnable, 200);
}
}
}
文件上传与下载
文件上传
添加文件选择器依赖后,重写UIController处理文件选择:
public class CustomUIController extends DefaultUIController {
public CustomUIController(AppCompatActivity activity) {
super(activity);
}
@Override
public void onSelectFile(FileChooser fileChooser) {
// 自定义文件选择逻辑
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, FILE_REQUEST_CODE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FILE_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
mFileChooser.onResult(data.getData());
}
}
}
// 使用自定义UIController
.setAgentWebUIController(new CustomUIController(this))
文件下载
AgentWeb集成了Downloader库,支持断点续传和通知栏提示:
// 简单下载
DefaultDownloadImpl.create(mActivity, mAgentWeb.getPermissionInterceptor())
.download(url, savePath, fileName, new DownloadListener() {
@Override
public void onStart(String path) {}
@Override
public void onProgress(String path, long loaded, long total) {}
@Override
public void onFinish(String path) {}
@Override
public void onError(String path, String error) {}
});
JS与Native交互
Native调用JS
// 无返回值调用
mAgentWeb.getJsAccessEntrace().quickCallJs("javascript:showToast('Hello from Native')");
// 带返回值调用
mAgentWeb.getJsAccessEntrace().quickCallJs("javascript:sum(1,2)", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
Log.d("JSResult", "Sum result: " + value);
}
});
JS调用Native
创建交互接口类:
public class AndroidInterface {
private Context mContext;
public AndroidInterface(Context context) {
mContext = context;
}
@JavascriptInterface
public void showToast(String msg) {
Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
}
@JavascriptInterface
public String getDeviceInfo() {
return Build.MODEL + "/" + Build.VERSION.RELEASE;
}
}
// 注册接口
mAgentWeb.getJsInterfaceHolder().addJavaObject("android", new AndroidInterface(this));
在JS中调用:
// 调用Native方法
window.android.showToast('Hello from JS');
var deviceInfo = window.android.getDeviceInfo();
自定义WebSettings
通过继承AbsAgentWebSettings实现自定义配置:
public class CustomSettings extends AbsAgentWebSettings {
@Override
public IAgentWebSettings toSetting(WebView webView) {
super.toSetting(webView);
// 基础设置
getWebSettings().setBlockNetworkImage(false);
getWebSettings().setAllowFileAccess(false);
// 安全设置
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
getWebSettings().setAllowFileAccessFromFileURLs(false);
getWebSettings().setAllowUniversalAccessFromFileURLs(false);
}
// 编码与字体设置
getWebSettings().setDefaultTextEncodingName("UTF-8");
getWebSettings().setDefaultFontSize(16);
return this;
}
}
// 使用自定义设置
.setAgentWebSettings(new CustomSettings())
高级应用
生命周期管理
AgentWeb提供WebLifeCycle接口,便于与Activity/Fragment生命周期同步:
// 在Fragment中使用
public class WebFragment extends Fragment {
private AgentWeb mAgentWeb;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_web, container, false);
mAgentWeb = AgentWeb.with(this)
.setAgentWebParent((ViewGroup) view.findViewById(R.id.container), new FrameLayout.LayoutParams(-1, -1))
.useDefaultIndicator()
.createAgentWeb()
.ready()
.go("https://www.example.com");
return view;
}
@Override
public void onPause() {
mAgentWeb.getWebLifeCycle().onPause();
super.onPause();
}
@Override
public void onResume() {
mAgentWeb.getWebLifeCycle().onResume();
super.onResume();
}
@Override
public void onDestroyView() {
mAgentWeb.getWebLifeCycle().onDestroy();
super.onDestroyView();
}
}
拦截器使用
通过拦截器实现URL重定向、资源加载控制等功能:
.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("scheme://")) {
// 处理自定义协议
handleScheme(url);
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
// 页面加载完成后执行
}
})
常见问题解决方案
1. 支付宝/微信支付集成
支付宝需要额外引入SDK,微信支付无需特殊处理:
// 支付宝集成
implementation files('libs/alipaySdk-20180601.jar')
// 支付页面加载
mAgentWeb = AgentWeb.with(this)
.setAgentWebParent(container, params)
.useDefaultIndicator()
.createAgentWeb()
.ready()
.go(payUrl);
2. 视频全屏播放
自定义WebChromeClient处理视频全屏:
.setWebChromeClient(new WebChromeClient() {
@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
super.onShowCustomView(view, callback);
// 处理全屏逻辑
if (view instanceof FrameLayout) {
FrameLayout frameLayout = (FrameLayout) view;
if (frameLayout.getFocusedChild() instanceof VideoView) {
VideoView videoView = (VideoView) frameLayout.getFocusedChild();
// 全屏显示视频
}
}
}
@Override
public void onHideCustomView() {
super.onHideCustomView();
// 退出全屏
}
})
3. 内存泄漏防护
正确管理AgentWeb生命周期,在Activity销毁时彻底释放资源:
@Override
protected void onDestroy() {
// 先停止WebView
mAgentWeb.getWebLifeCycle().onDestroy();
// 移除View引用
ViewGroup parent = (ViewGroup) mAgentWeb.getWebCreator().getWebParentLayout();
if (parent != null) {
parent.removeAllViews();
}
// 清除AgentWeb实例
mAgentWeb = null;
super.onDestroy();
}
性能优化建议
- 资源预加载:对常用页面进行预加载,减少用户等待时间
- 图片懒加载:通过WebView设置延迟加载图片
- 硬件加速:在AndroidManifest.xml中为Activity启用硬件加速
- 缓存策略:合理配置缓存模式,减少网络请求
- WebView池:在频繁使用WebView的场景下,使用对象池复用WebView实例
// 缓存策略配置
getWebSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
getWebSettings().setAppCacheEnabled(true);
getWebSettings().setAppCachePath(getCacheDir().getPath());
getWebSettings().setDatabaseEnabled(true);
总结
AgentWeb通过封装WebView的复杂逻辑,提供简洁API的同时保留了灵活性。从基础的页面加载到高级的JS交互,从文件处理到生命周期管理,AgentWeb都提供了完善的解决方案。通过本文介绍的快速集成、核心功能和最佳实践,开发者可以在短时间内构建稳定高效的WebView应用。
AgentWeb的强大之处在于其扩展性,开发者可以根据项目需求定制WebSettings、UIController和各种拦截器,实现企业级WebView应用。建议结合Sample项目深入学习,探索更多高级特性。
扩展学习
- AgentWeb X5内核集成:支持腾讯X5内核,提升兼容性
- 离线包方案:结合ServiceWorker实现离线缓存
- 安全加固:实现URL白名单、JS注入防护等安全措施
- 性能监控:集成WebView性能监控,优化加载速度
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



