Skip to content

Commit

Permalink
1.3.0 分支重构代码
Browse files Browse the repository at this point in the history
  • Loading branch information
杨充 committed May 31, 2020
1 parent e8dcfca commit f3677bc
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 36 deletions.
Binary file modified .idea/caches/build_file_checksums.ser
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ public class X5WebViewClient extends WebViewClient {
* 记录重定向前的链接
*/
private String mUrlBeforeRedirect;
private static int ERR_TOO_MANY_REDIRECTS = -9;

/**
* 获取是否加载完毕
Expand Down Expand Up @@ -124,6 +123,7 @@ public X5WebViewClient(WebView webView ,Context context) {
* @param url 链接
*/
private void recordUrl(String url) {
//判断当前url,是否和栈中栈顶部的url是否相同。如果不相同,则入栈操作
if (!TextUtils.isEmpty(url) && !url.equals(getUrl())) {
if (!TextUtils.isEmpty(mUrlBeforeRedirect)) {
mUrlStack.push(mUrlBeforeRedirect);
Expand All @@ -139,6 +139,7 @@ private void recordUrl(String url) {
*/
@Nullable
public String getUrl() {
//peek方法,查看此堆栈顶部的对象,而不将其从堆栈中删除。
return mUrlStack.size() > 0 ? mUrlStack.peek() : null;
}

Expand All @@ -147,6 +148,7 @@ public String getUrl() {
* @return
*/
String popUrl() {
//pop方法,移除此堆栈顶部的对象并将该对象作为此函数的值返回。
return mUrlStack.size() > 0 ? mUrlStack.pop() : null;
}

Expand Down Expand Up @@ -391,7 +393,8 @@ public void onReceivedError(WebView view, int errorCode, String description, Str
super.onReceivedError(view, errorCode, description, failingUrl);
X5LogUtils.i("-------onReceivedError-------"+failingUrl);
if (Build.VERSION.SDK_INT < 23) {
if (errorCode == ERR_TOO_MANY_REDIRECTS) {
//错误重定向循环
if (errorCode == ERROR_REDIRECT_LOOP) {
resolveRedirect(view);
return;
}
Expand Down Expand Up @@ -448,7 +451,8 @@ public void onReceivedError(WebView view, WebResourceRequest request, WebResourc
super.onReceivedError(view, request, error);
X5LogUtils.i("-------onReceivedError-------"+error.getDescription().toString());
if (Build.VERSION.SDK_INT >= 23) {
if (error != null && error.getErrorCode() == ERR_TOO_MANY_REDIRECTS) {
//错误重定向循环
if (error != null && error.getErrorCode() == ERROR_REDIRECT_LOOP) {
resolveRedirect(view);
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ public WebAssetsLoader init(Context context){
return this;
}

/**
* 获取url的path路径
* @param url url链接
* @return
*/
private String getUrlPath(String url){
String uPath="";
try {
Expand Down Expand Up @@ -144,7 +149,7 @@ private void addAssetsFile(String file){

private WebAssetsLoader initResourceNoneRecursion(String dir){
try {
LinkedList<String> list = new LinkedList<String>();
LinkedList<String> list = new LinkedList<>();
String[] resData = mContext.getAssets().list(dir);
if (resData != null) {
for (String res : resData) {
Expand Down Expand Up @@ -188,6 +193,11 @@ private WebAssetsLoader initResourceNoneRecursion(String dir){
return this;
}

/**
* 从本地文件中获取数据,将file文件转化成数据流InputStream
* @param path
* @return
*/
public InputStream getAssetFileStream(String path) {
try {
//读取assets路径下的文件
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ public static boolean isSilentType(@NonNull String scheme) {
* @return true表示被处理
*/
public static boolean handleAlive(@NonNull Context context, Uri uri) {
if (uri==null){
return false;
}
final String scheme = uri.getScheme();
if (TextUtils.isEmpty(scheme) || !isAliveType(scheme)) {
return false;
Expand Down
70 changes: 47 additions & 23 deletions read/WebShare.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
#### WebView分享目录介绍
#### 目录介绍
- 01.loadUrl到底做了什么
- 02.触发加载网页的行为
- 03.webView重定向怎么办
- 04.js交互的一点知识分享
- 05.拦截缓存如何优雅处理
- 06.关于一些问题和优化
- 07.关于一点面向对象的思想
- 08.关于后期需要研究的目标
- 07.关于一点面向对象思想
- 08.关于后期需要研究目标



### loadUrl到底做了什么
### 01.loadUrl到底做了什么
- WebView.loadUrl(url)加载网页做了什么?
- 加载网页是一个复杂的过程,在这个过程中,我们可能需要执行一些操作,包括:
- 加载网页前,重置WebView状态以及与业务绑定的变量状态。WebView状态包括重定向状态(mTouchByUser)、前端控制的回退栈(mBackStep)等,业务状态包括进度条、当前页的分享内容、分享按钮的显示隐藏等。
Expand All @@ -28,7 +28,7 @@



### 触发加载网页的行为
### 02.触发加载网页的行为
- 触发加载网页的行为主要有两种方式:
- (A)点击页面,触发<link>标签。
- (B)调用WebView的loadUrl()方法
Expand Down Expand Up @@ -113,30 +113,51 @@



### webView重定向怎么办
### 03.webView重定向怎么办
- webView出现302/303重定向
- 302重定向又称之为302代表暂时性转移,比如你跳转A页面,但由于网页添加了约束条件,可能让你跳转到B页面,甚至多次重定向。
- 导致的问题
- 1.A-->B-->C,比如你跳转A页面,最终重定向到C页面。这个时候调用goBack方法,返回到B链接,但是B链接又会跳转到C链接,从而导致没法返回到A链接界面
- 2.会多次执行onPageStarted和onPageFinished,如果你这里有加载进度条或者loading,那么会导致进度条或者loading执行多次
- 3.
- 如何判断页面发生重定向




### js交互的一点知识分享
- 常见的解决方案
- 手动管理回退栈,遇到重定向时回退两次。
- 通过HitTestResult判断是否是重定向,从而决定是否自己加载url。具体看:[16.301/302回退栈问题解决方案2](https://github.com/yangchong211/YCWebView/wiki/6.2-webView%E5%9F%BA%E7%A1%802)
- 通过设置标记位,在onPageStarted和onPageFinished分别标记变量避免重定向。具体看:[17.301/302回退栈问题解决方案3](https://github.com/yangchong211/YCWebView/wiki/6.2-webView%E5%9F%BA%E7%A1%802)
- 通过用户的touch事件来判断重定向。具体看:[15.301/302回退栈如何处理1](https://github.com/yangchong211/YCWebView/wiki/6.2-webView%E5%9F%BA%E7%A1%802)
- 如何判断重定向
- 通过getHitTestResult()返回值,如果返回null,或者UNKNOWN_TYPE,则表示为重定向。具体看:[18.如何用代码判断是否重定向](https://github.com/yangchong211/YCWebView/wiki/6.2-webView%E5%9F%BA%E7%A1%802)
- 在加载一个页面开始的时候会回调onPageStarted方法,在该页面加载完成之后会回调onPageFinished方法。而如果该链接发生了重定向,回调shouldOverrideUrlLoading会在回调onPageFinished之前。
- 终极解决方案如下
- 需要准备的条件
- 创建一个栈,主要是用来存取和移除url的操作。这个url包括所有的请求链接
- 定义一个变量,用于判断页面是否处于正在加载中。
- 定义一个变量,用于记录重定向前的链接url
- 定一个重定向时间间隔,主要为了避免刷新造成循环重定向
- 具体怎么操作呢
- 在执行onPageStarted时,先移除栈中上一个url,然后将url加载到栈中。
- 当出现错误重定向的时候,如果和上一次重定向的时间间隔大于3秒,则reload页面。
- 在回退操作的时候,判断如果可以回退,则从栈中获取最后停留的url,然后loadUrl。即可解决回退问题。
- 具体方法思路
- 可以看:[20.重定向终极优雅解决方案](https://github.com/yangchong211/YCWebView/wiki/6.2-webView%E5%9F%BA%E7%A1%802)
- 具体代码看:[X5WebViewClient](https://github.com/yangchong211/YCWebView/blob/master/WebViewLib/src/main/java/com/ycbjie/webviewlib/base/X5WebViewClient.java)



### 04.js交互的一点知识分享
- js交互介绍
- Java调用js方法有两种:
- WebView.loadUrl("javascript:" + javascript);
- WebView.evaluateJavascript(javascript, callbacck);
- js调用Java的方法有四种,分别是:
- js调用Java的方法有三种,分别是:
- JavascriptInterface
- WebViewClient.shouldOverrideUrlLoading()
- WebChromeClient.onConsoleMessage()
- WebChromeClient.onJsPrompt()
- js调用java方法比较和区别分析
-
- 1.通过 addJavascriptInterface 方法进行添加对象映射。js最终通过对象调用原生方法
- 2.shouldOverrideUrlLoading拦截操作,获取scheme匹配,与网页约定好一个协议,如果匹配,执行相应操作
- 3.利用WebChromeClient回调接口onJsPrompt拦截操作。
- onJsAlert 是不能返回值的,而 onJsConfirm 只能够返回确定或者取消两个值,只有 onJsPrompt 方法是可以返回字符串类型的值,操作最全面方便。
- 详细分析可以看:[03.Js调用Android](https://github.com/yangchong211/YCWebView/wiki/6.1-webView%E5%9F%BA%E7%A1%801)
- js调用java原生方法可能存在的问题?
- 提出问题
- 1.原生方法是否可以执行耗时操作,如果有会阻塞通信吗?[4.4.8 prompt的一个坑导致js挂掉](https://github.com/yangchong211/YCWebView/wiki/4.4-%E9%97%AE%E9%A2%98%E6%B1%87%E6%80%BB%E4%BB%8B%E7%BB%8D4)
Expand All @@ -157,7 +178,7 @@



### 拦截缓存如何优雅处理
### 05.拦截缓存如何优雅处理
- WebView为何加载慢
- webView是怎么加载网页的呢?
- webView初始化->DOM下载→DOM解析→CSS请求+下载→CSS解析→渲染→绘制→合成
Expand Down Expand Up @@ -218,7 +239,9 @@



### 关于一些问题和优化


### 06.关于一些问题和优化
- 影响页面加载的一些因素有那些?
- 1.加载网页中,如果图片很多,而这些图片的请求又是一个个独立并且串行的请求。那么可能会导致加载页面比较缓慢……
- 2.app原生和webView中请求,都会涉及到https的网络请求,那么在请求前会有域名dns的解析,这个也会有大约200毫秒的解析时间(主要耗费时间dns,connection,服务器处理等)……
Expand All @@ -244,7 +267,7 @@



### 关于一点面向对象的思想
### 07.关于一点面向对象的思想
- 针对webView视频播放演变
- 1.最刚开始把视频全屏show和hide的逻辑都放到X5WebChromeClient中处理,相当于这个类中逻辑比较多
- 2.后期把视频全屏播放逻辑都抽到了VideoWebChromeClient类中处理,这样只需要继承该类即可。这个类独立,拿来即用。
Expand All @@ -266,18 +289,19 @@



### 关于后期需要研究的目标
### 08.关于后期需要研究的目标
- 目标
- web页面特别消耗流量,每次打开页面都会请求网络,建议对流量的消耗进行优化……
- web页面特别消耗流量,每次打开页面都会请求网络,建议对流量的消耗进行优化……除了对lib库中对拦截做OkHttp缓存,还有什么其他方案
- web页面涉及流量的几个方面
- 普通https请求,一般过程是服务端(对象)-->网络中(二进制流)-->客户端(对象),文本内容会做传输压缩
- 普通https请求,一般过程是服务端(对象)-->网络中(二进制流)-->客户端(对象),文本内容会做传输压缩
- 网络图片下载,图片下载消耗的流量较多
- h5页面展示,由于h5页面是交由前端处理显示,客户端开发关注的少些,而此处消耗了大量的流量
- 如何查看web页面消耗流量
- 使用TrafficStats即可查看流量的消耗



### 09.开源库
- https://github.com/yangchong211/YCWebView



4 changes: 3 additions & 1 deletion read/WebView1.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,9 @@
alert("open activity " + result);
}
```
- 需要注意的是 prompt 里面的内容是通过 message 传递过来的,并不是第二个参数的 url,返回值是通过 JsPromptResult 对象传递。为什么要拦截 onJsPrompt 方法,而不是拦截其他的两个方法,这个从某种意义上来说都是可行的,但是如果需要返回值给 web 端的话就不行了,因为 onJsAlert 是不能返回值的,而 onJsConfirm 只能够返回确定或者取消两个值,只有 onJsPrompt 方法是可以返回字符串类型的值,操作最全面方便。
- 需要注意的是 prompt 里面的内容是通过 message 传递过来的,并不是第二个参数的 url,返回值是通过 JsPromptResult 对象传递。
- 为什么要拦截 onJsPrompt 方法,而不是拦截其他的两个方法,这个从某种意义上来说都是可行的,但是如果需要返回值给 web 端的话就不行了。
- 因为 onJsAlert 是不能返回值的,而 onJsConfirm 只能够返回确定或者取消两个值,只有 onJsPrompt 方法是可以返回字符串类型的值,操作最全面方便。
- 以上三种方案的总结和对比
- 以上三种方案都是可行的,在这里总结一下
- 第一种方式:是现在目前最普遍的用法,方便简洁,但是唯一的不足是在 4.2 系统以下存在漏洞问题;
Expand Down
Loading

0 comments on commit f3677bc

Please sign in to comment.