我有一个活动,它通过拦截重定向URL来进行OAuth身份验证,一旦它出现在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())。
9条答案
按热度按时间n6lpvg4x1#
如果onPageStarted方法启动onPageFinished后URL正常,但如果在onPageStarted启动shouldOverrideUrlLoading然后onPageFinished后URL被重定向。你只需要检查加载URL是否被重定向
如果URL被重定向,则回调将启动此函数
在onPageFinished中执行某些操作之前,请检查回调是否已进入shouldOverrideUrlLoading方法
sulc1iza2#
也许它能帮助某人。
我有一些问题-方法onPageFinished调用了两次。
System. out. println();
在第一次执行时webView.getProgress()== 89,在第二次执行时== 100。100表示页面加载完成。
wvt8vs2t3#
所以,上面的答案都没有给我一个解决方案,因为我的问题不是重定向,webview只是在同一个网页上调用onPageFinished 3次。我的解决方案如下,主要思想是在同一个URL上执行一次功能。
olhwl3o24#
我正在查看一个事件,其中m.yotube.com触发了两个onPageFinished事件,但对我来说,它似乎不是由重定向引起的。经过一些研究,我发现在didStopLoading触发的onPageFinished之前,还有一个额外的onPageFinished由didFinishNavigation触发,其他页面也会收到。
参见:
https://chromium.googlesource.com/chromium/src.git/+/master/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java
另一个例子是我收到了额外的onPageFinished调用(甚至在onPageStarted之前!)是我在Fragments中使用webview.restoreState()的时候。它在尝试恢复上次查看的页面时触发两个onPageFinished事件。
vsikbqxv5#
Android出于某种原因调用onPageFinished()两次(和onPageStarted()三次!)当加载的URL不是工作URL时。临时解决方案是将redirect_uri更改为工作网站的url;在这种情况下,我将其更改为https://www.google.com/(lol,对不起Google)。onPageFinished只被调用一次。
但是-我仍然想知道为什么当加载的URL不是一个工作的URL时,webview的行为会有所不同,以及什么是比将redirect_uri更改为google.com更好的解决方案。
gxwragnw6#
这个技巧帮助我(不推荐,但帮助)
rkkpypqq7#
由于onPageFinished被多次调用,因此在执行任何进一步操作之前,您只需检查该方法是否已被调用。
rqcrx0a68#
这里有一个更好的解决方案(不是最好的)。由于(在我的情况下)第二次触发非常快,我假设我可以依赖
System.currentTimeMillis()
,如下所示:该解决方法防止任何其他(短时间,1000 ms)链式触发,并且它从第一个触发调用parsePage()。无论如何,复杂的网页/网站不会在
onPageFinished()
触发器上准备好,因为javascript(计数器/帧/web-api-calls/等)正在运行。通常,如果要解析页面,应该在onPageFinished()
触发器之后等待一段时间。ujv3wf0j9#
解决方案的最佳途径;
问题--> Android设备onPagefinished调用两次。(IOS设备没有问题)
解决方案-->在OnLoadStop之前你可以调用定义bool参数的onLoadStart方法。
*onLoadStart:(controller,url)async{ //bool param define this section },
*onLoadStop:(controller,url)async { if(bool param){ // than control
enter code here
} }