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==============

posted @ 2019-03-06 18:27  绿叶萌飞  阅读(917)  评论(0编辑  收藏  举报