Android- Webview onPageFinished被称为两次

Ste*_*hen 23 android android-webview

我有一项活动通过在网页浏览中显示重定向网址时拦截重定向网址来执行OAuth身份验证.但是,由于某种原因,onPageFinished函数以某种方式被调用两次,这真的弄乱了我的应用程序.这是代码:

public class WebViewActivity extends Activity {
private WebView gWebView;
final String REDIRECT_URI = "https://localhost:5000/receive_code";
final String CLIENT_ID = "can't post it here";
final String CLIENT_SECRET = "can't post it here";
final String SCOPE = "basic names genomes analyses";
Hashtable<String, String> riskPairs;

public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.webview);

    gWebView = (WebView) findViewById(R.id.webView1);

    gWebView.loadUrl("https://api.23andme.com/authorize/?redirect_uri="
            + REDIRECT_URI + "&response_type=code&client_id=" + CLIENT_ID
            + "&scope=" + SCOPE);

    Log.d("WEBVIEW", "got to webpage");

    gWebView.setWebViewClient(new WebViewClient() {

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            if (url.startsWith(REDIRECT_URI)) {
                Log.d("WEBVIEW", "onpagefinished is called");
                System.out.println("got to override");
                if (url.indexOf("code=") != -1) {
                    //if the query contains code
                    String queryString = null;
                    try {
                        queryString = new URL(url).getQuery();
                    } catch (MalformedURLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println(queryString);
                    String[] params = queryString.split("&");
                    String code = null;
                    for (String param : params) {
                        if (param.startsWith("code=")) {
                            code = param.substring(param.indexOf('=') + 1);
                        }
                    }
                    gWebView.setVisibility(View.GONE);
                    new PostRequest().execute(code);
                    // don't go to redirectUri
                }
            }
        }
    });


}
class PostRequest extends AsyncTask<String,Void,String>{ code getting client data...}
Run Code Online (Sandbox Code Playgroud)

PS请不要将其标记为重复...我在StackOverflow上阅读了类似的问题,调用ShouldOverrideUrlLoading对我不起作用(这就是为什么我首先使用onPageFinished()).

小智 28

如果在onPageStarted方法启动onPageFinished后url是OK,但是如果在onPageStarted启动之后重定向url,则启动shouldOverrideUrlLoading然后onPageFinished.您应该检查是否重定向加载URL

private boolean isRedirected;

@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {   

  if (!isRedirected) {      
    //Do something you want when starts loading
  }

  isRedirected = false;
}
Run Code Online (Sandbox Code Playgroud)

如果重定向URL,则回调将启动此功能

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {

  view.loadUrl(url);
  isRedirected = true;
  return true;
}
Run Code Online (Sandbox Code Playgroud)

在onPageFinished中执行某些操作之前,请检查回调是否已输入shouldOverrideUrlLoading方法

@Override
public void onPageFinished(WebView view, String url) {

  if (!isRedirected) {
    //Do something you want when finished loading 
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 我的 webview 没有调用 shouldOverrideUrlLoading(我为 sdk 24 及更小版本添加了两个函数 shouldOverrideUrlLoading) (2认同)

小智 9

也许它可以帮助某人。

我有一些问题 - onPageFinished 方法调用了两次。

webView.getProgress();

第一次执行 webView.getProgress() == 89,第二次执行 == 100。100 表示页面加载完成。


Bal*_* F. 8

所以,以上答案都没有给我一个解决方案,因为我的问题不是重定向,webview 只是在同一个网页上调用了 onPageFinished 3 次。我的解决方案如下,主要思想是在同一个 url 上只执行一次你的功能。

private String urlFinished = " ";

@Override
public void onPageFinished(WebView view, String url) {

    Logger.d(TAG, "onPageFinished");

    if (!urlFinished.equals(url)) {
      //Place your code here
    }

    urlFinished = url;

    super.onPageFinished(view, url);
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的解决方法,但它也会产生一个问题,即刷新加载相同 url 的页面(比如 10 秒后),它不会触发。解决这个问题的最简单方法是添加一个计时器(https://developer.android.com/reference/java/util/Timer),它将在 X 秒后将 url 设置回空字符串,具体取决于您需要多少。 (2认同)