2013-08-16 86 views
18

私は、Webビューに表示されたリダイレクトURLを傍受してOAuth認証を行うアクティビティを持っています。しかし、何らかの理由でonPageFinished関数が何とか2回呼び出されてしまい、アプリケーションが実際にはうんざりしてしまいます。コードは次のとおりです。Android-Webview onPageFinished2回呼び出されました

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

onPageStarted方法はonPageFinishedを開始した後、しかし、URLがリダイレクトされている場合 onPageStartedはshouldOverrideUrlLoadingを開始し、onPageFinished後にURLがOKであれば。 ロードURLがリダイレクトまたはURLがリダイレクトされている場合は、コールバックがshouldOverrideUrlLoadingに入っている場合ではない

private boolean isRedirected; 

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

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

    isRedirected = false; 
} 

コールバックがonPageFinishedチェックで何かを行う前に、この機能

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

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

を開始されている場合は、単にチェックする必要があります方法

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

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

これは私の場合ではありません –

+0

これはまったく動作しませんでした –

2

Androidは、何らかの理由で、ロードされたURLが動作していないときに、PageFinished()を2回(onPageStarted()を3回呼び出す)呼び出します。一時的な解決策は、redirect_uriを動作中のWebサイトのURLに変更しています。この場合、私はそれをhttps://www.google.com/に変更しました(lol、すみませんGoogle)。 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が2つのonPageFinishedイベントをトリガしますが、私にリダイレクトによって引き起こされるように、それは思われないイベントに探しています。いくつかの調査の後、私は、他のページも受信するdidStopLoadingによってトリガーされる前に、didFinishNavigationによってトリガーされた1つの追加の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; 
     } 
    } 

別のインスタンス私は(さえonPageStarted前に!)余分onPageFinished電話を受ける私はwebview.restoreStateを(利用する場合である)の断片で。最後に表示されたページを再開しようとすると、2つのonPageFinishedイベントが発生します。

関連する問題