2013-08-16 141 views
18

我有一個活動,通過在webview中顯示重定向url後攔截重定向url來執行OAuth身份驗證。然而,onPageFinished函數由於某種原因以某種方式被調用了兩次,這真的弄亂了我的應用程序。以下是代碼:Android Webview 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...} 

P.S. 請不要將此標記爲重複項...我已閱讀StackOverflow上的類似問題,並調用ShouldOverrideUrlLoading對我不起作用(這就是爲什麼我首先使用onPageFinished())。

回答

22

如果url是OK後onPageStarted方法開始onPageFinished,但如果URL是 後重定向onPageStarted開始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; 
} 

如果URL重定向回調啓動此功能

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

    view.loadUrl(url); 
    isRedirected = true; 
    return true; 
} 

如果回調已進入shouldOverrideUrlLoading在做onPageFinished檢查東西之前方法

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

    if (!isRedirected) { 
    //Do something you want when finished loading 
    } 
} 
+0

這不是我的情況 –

+0

這完全沒有工作 –

2

由於某些原因,當加載的url不是工作的時,Android會因某種原因調用onPageFinished()兩次(和onPageStarted()三次!臨時解決方案是將redirect_uri更改爲工作網站的網址;在這種情況下,我將其更改爲https://www.google.com/(哈哈,對不起谷歌)。 onPageFinished然後只被調用一次。

但我仍然想回答爲什麼在加載的url不是工作的時候webview的行爲不同,以及比redirect_uri更改爲google.com更好的解決方案。

+1

可以請你幫我在相同的情況下,我在截止日期 –

0

這一招可以幫助我(不推薦,但幫助)

private boolean alreadyEvaluated = false; 

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

     Logger.d(TAG, "onPageStarted"); 

     super.onPageStarted(view, url, favicon); 
    } 

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

     Logger.d(TAG, "onPageFinished"); 

     if (!alreadyEvaluated) { 
      alreadyEvaluated = true; 
      view.loadUrl("javascript:window.MyJavaScript.getPageText(document.getElementsByTagName('body')[0].innerText);"); 
     } else { 
      alreadyEvaluated = false; 
     } 

     super.onPageFinished(view, url); 
    } 
1

我尋找到一個事件,其中m.yotube.com觸發兩個onPageFinished事件,但它似乎並不像造成重定向到我。經過一些研究後,我發現在由didStopLoading觸發的一個由didFinishNavigation觸發的一個額外的onPageFinished中,其他頁面也會收到這個額外的onPageFinished。

stack trace #1 stack trace #2

參見:

https://chromium.googlesource.com/chromium/src.git/+/master/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java

@Override 
    public void didFinishNavigation(final String url, boolean isInMainFrame, boolean isErrorPage, 
      boolean hasCommitted, boolean isSameDocument, boolean isFragmentNavigation, 
      Integer pageTransition, int errorCode, String errorDescription, int httpStatusCode) { 
     ... 
     if (client != null && isFragmentNavigation) { 
      client.getCallbackHelper().postOnPageFinished(url); 
     } 
    } 

    @Override 
    public void didStopLoading(String validatedUrl) { 
     if (validatedUrl.length() == 0) validatedUrl = ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL; 
      AwContentsClient client = getClientIfNeedToFireCallback(validatedUrl); 
     if (client != null && validatedUrl.equals(mLastDidFinishLoadUrl)) { 
      client.getCallbackHelper().postOnPageFinished(validatedUrl); 
     mLastDidFinishLoadUrl = null; 
     } 
    } 

另一個例子中,我獲得額外onPageFinished電話(!甚至onPageStarted前),當我在片段利用webview.restoreState() 。當嘗試恢復上次瀏覽的頁面時,它會觸發兩個onPageFinished事件。

相關問題