android学习笔记----WebView的url跳转时方法执行顺序体会
先上一部分代码:
MainActivity.java
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
private EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.edittext);
}
public void click(View view) {
switch (view.getId()) {
case R.id.button1:
Intent intent = new Intent(this, WebViewActivity.class);
intent.putExtra("url", editText.getText().toString());
startActivity(intent);
break;
case R.id.button2:
Intent intent1 = new Intent(this, WebViewActivity.class);
intent1.putExtra("url", "https://www.google.com/");
startActivity(intent1);
break;
default:
}
}
}
测试图:
WebViewActivity.java(这段代码访问google的时候有点问题,后续说明)
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.Toast;
public class WebViewActivity extends AppCompatActivity {
private static final String TAG = "WebViewActivity";
private WebView webView;
private WebViewClient webViewClient = new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
Log.d(TAG, "======shouldOverrideUrlLoading: " + view.getUrl());
if (view.getUrl().equals("https://www.google.com/")) {
// !!!=======如果写在这里将永远得不到执行,访问国外网站根本不回调shouldOverrideUrlLoading
Toast.makeText(WebViewActivity.this, "国内无法访问国外的网站", Toast.LENGTH_SHORT).show();
return true;// 停止继续加载该url
}
return super.shouldOverrideUrlLoading(view, request);// 默认返回false继续加载
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {// 可能涉及重定向导致再次调用此方法
Log.d(TAG, "========onPageStarted: " + url);
progressBar.setVisibility(View.VISIBLE);
}
@Override
public void onPageFinished(WebView view, String url) {
Log.d(TAG, "========onPageFinished: ");
progressBar.setVisibility(View.GONE);
}
};
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view);
webView = (WebView) findViewById(R.id.webview);
progressBar = (ProgressBar) findViewById(R.id.progressbar);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);// 加上这句很重要,否则加载不全网页效果
webView.setWebViewClient(webViewClient);
Intent intent = getIntent();
String url = completeUrl(intent.getStringExtra("url"));
Log.d(TAG, "=======onCreate: url:" + url);
webView.loadUrl(url);
}
private String completeUrl(String url) {
if (!url.substring(0, 7).equals("http://") && !url.substring(0, 8).equals("https://")) {
return "http://" + url;
}
return url;
}
}
荣耀v9(8.0.0)真机结果:(在模拟器上往往会出现shouldOverrideUrlLoading在onPageStarted前面的情况)
所以在这里,得出的结论是
当访问的目标地址需要重定向的时候:
方法的执行顺序:onPageStarted()-->shouldOverrideUrlLoading()-->onPageStarted()-->onPageFinished()。多一次重定向就多一个onPageStarted()。
当访问的目标地址不需要重定向的时候:
方法的执行顺序:onPageStarted()-->onPageFinished()
这又有了一个问题,当我点击第二个按钮访问google的时候,出现了问题! 没有很快执行onPageFinished(),网页没加载出来,我们想要提醒用户国内无法访问google,但是似乎shouldOverrideUrlLoading的
if (view.getUrl().equals("https://www.google.com/")) {
Toast.makeText(WebViewActivity.this, "国内无法访问google", Toast.LENGTH_SHORT).show();
return true;// 停止继续加载该url
}
没有得到执行。
等了一会才出现下图:
于是乎,我加了一个让人很匪夷所思的空方法!!!
super.onPageStarted(view, url, favicon);//点进去看这个方法是空的。
public void onPageStarted(WebView view, String url, Bitmap favicon) {// 可能涉及重定向导致再次调用此方法
Log.d(TAG, "========onPageStarted: " + url);
progressBar.setVisibility(View.VISIBLE);
super.onPageStarted(view, url, favicon);//!!====少了这一句加载国外网站需要等待很久,加上立马显示不能访问google
}
WebViewActivity.java的代码变化如下:
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.Toast;
public class WebViewActivity extends AppCompatActivity {
private static final String TAG = "WebViewActivity";
private WebView webView;
private WebViewClient webViewClient = new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
Log.d(TAG, "======shouldOverrideUrlLoading: " + view.getUrl());
return super.shouldOverrideUrlLoading(view, request);// 默认返回false继续加载
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
Log.d(TAG, "======onReceivedError: ");
super.onReceivedError(view, request, error);
if (view.getUrl().equals("https://www.google.com/")) {
Toast.makeText(WebViewActivity.this, "国内无法访问国外的网站", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {// 可能涉及重定向导致再次调用此方法
Log.d(TAG, "========onPageStarted: " + url);
progressBar.setVisibility(View.VISIBLE);
super.onPageStarted(view, url, favicon);//!!====少了这一句加载国外网站需要等待很久,加上立马显示不能访问google
}
@Override
public void onPageFinished(WebView view, String url) {
Log.d(TAG, "========onPageFinished: ");
progressBar.setVisibility(View.GONE);
super.onPageFinished(view, url);
}
};
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view);
webView = (WebView) findViewById(R.id.webview);
progressBar = (ProgressBar) findViewById(R.id.progressbar);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);// 加上这句很重要,否则加载不全网页效果
webView.setWebViewClient(webViewClient);
Intent intent = getIntent();
String url = completeUrl(intent.getStringExtra("url"));
Log.d(TAG, "=======onCreate: url:" + url);
webView.loadUrl(url);
}
private String completeUrl(String url) {
if (!url.substring(0, 7).equals("http://") && !url.substring(0, 8).equals("https://")) {
return "http://" + url;
}
return url;
}
}
方法执行如下,立马显示不能执行。
如果需要加载自定义的错误界面,嫌弃诸如下面的界面太丑的话,可以自己写界面在onReceivedError方法进行操作,这样也不会暴露url。访问异常的情况比如404都会回调onReceivedError方法,正常情况下不会回调。
============Talk is cheap, show me the code==============