如何在Xamarin Android上使用C#在文档开始时注入Javascript
我正在尝试在VisualStudio中将一个应用程序从Swift(仅限iOS)移植到C#,而且进展(稍微)顺利。不过,我在安卓系统上遇到了一些问题(其中很多问题——但这个问题只有一个!) 页面在Android版本的应用程序的webview中正确加载,但Javascript直到页面呈现后才执行,结果是在应用程序商店广告消失之前短暂显示 我的iOS应用程序工作正常-iOS版本的源代码如下:如何在Xamarin Android上使用C#在文档开始时注入Javascript,c#,android,xamarin,xamarin.android,C#,Android,Xamarin,Xamarin.android,我正在尝试在VisualStudio中将一个应用程序从Swift(仅限iOS)移植到C#,而且进展(稍微)顺利。不过,我在安卓系统上遇到了一些问题(其中很多问题——但这个问题只有一个!) 页面在Android版本的应用程序的webview中正确加载,但Javascript直到页面呈现后才执行,结果是在应用程序商店广告消失之前短暂显示 我的iOS应用程序工作正常-iOS版本的源代码如下: public class PortalViewRenderer : ViewRenderer<Porta
public class PortalViewRenderer : ViewRenderer<PortalView, WKWebView>, IWKScriptMessageHandler, IWKNavigationDelegate {
private class NavigationDelegate : WKNavigationDelegate {
private readonly WeakReference<PortalViewRenderer> _webView;
public NavigationDelegate(PortalViewRenderer webView) {
_webView = new WeakReference<PortalViewRenderer>(webView);
}
public override void DidFinishNavigation(WKWebView webView, WKNavigation navigation) {
}
public override void DidStartProvisionalNavigation(WKWebView webView, WKNavigation navigation) {
NSUrl currentURL = webView.Url;
var current = Connectivity.NetworkAccess;
if (current != NetworkAccess.Internet) {
if (!(currentURL.AbsoluteString.Contains("file://"))) {
string noConnectionPath = Path.Combine(NSBundle.MainBundle.BundlePath, "Common/NoInternet.html");
webView.LoadRequest(new NSUrlRequest(NSUrl.FromString(noConnectionPath)));
}
}
}
public override void DidFailNavigation(WKWebView webView, WKNavigation navigation, NSError error) {
}
public override void DecidePolicy(WKWebView webView, WKNavigationAction navigationAction, Action<WKNavigationActionPolicy> decisionHandler) {
NSUrl url = navigationAction.Request.Url;
if (url != null) {
if (url.Host == "<website url>" || url.AbsoluteString.Contains("file://")) {
decisionHandler(WKNavigationActionPolicy.Allow);
} else if (url.AbsoluteString.Contains("<website url>/mydavylamp/timeout")) {
decisionHandler(WKNavigationActionPolicy.Cancel);
webView.LoadRequest(new NSUrlRequest(NSUrl.FromString(Element.Uri)));
} else {
UIApplication.SharedApplication.OpenUrl(url);
}
}
}
}
WKUserContentController userController;
protected override void OnElementChanged (ElementChangedEventArgs<PortalView> e) {
base.OnElementChanged (e);
var javaScriptFunction = System.IO.File.ReadAllText("Common/HideAppStoreAds.js");
if (Control == null) {
userController = new WKUserContentController();
var script = new WKUserScript(new NSString(javaScriptFunction), WKUserScriptInjectionTime.AtDocumentStart, false);
userController.AddUserScript(script);
userController.AddScriptMessageHandler(this, "invokeAction");
var config = new WKWebViewConfiguration { UserContentController = userController };
var webView = new WKWebView(Frame, config);
webView.BackgroundColor = UIKit.UIColor.FromRGB(0x11, 0x25, 0x43);
webView.ScrollView.BackgroundColor = webView.BackgroundColor;
webView.CustomUserAgent = "headbanger.davylamp.ios";
webView.ScrollView.ScrollEnabled = true;
webView.ScrollView.Bounces = false;
webView.AllowsBackForwardNavigationGestures = false;
webView.ContentMode = UIKit.UIViewContentMode.ScaleToFill;
webView.NavigationDelegate = new NavigationDelegate(this);
SetNativeControl(webView);
}
if (e.OldElement != null) {
userController.RemoveAllUserScripts();
userController.RemoveScriptMessageHandler("invokeAction");
var portalView = e.OldElement as PortalView;
portalView.Cleanup();
}
if (e.NewElement != null) {
Control.LoadRequest(new NSUrlRequest(NSUrl.FromString(Element.Uri)));
}
}
public void DidReceiveScriptMessage (WKUserContentController userContentController, WKScriptMessage message) {
Element.InvokeAction (message.Body.ToString ());
}
}
我在谷歌上搜索了这个魔咒,但我似乎找不到任何关于如何用C#为Android构建网络视图的指南,尤其是对于iOS开发者
和往常一样,任何人能够提供的任何帮助都会得到感激。对于我的用例,答案似乎如下 onPageCommitVisible的Android文档()说明: 此回调可用于确定使回收的WebView可见的安全点,以确保不显示过时的内容。它在最早的时候被调用,可以保证WebView#onDraw不再从以前的导航中提取任何内容。下一个绘图将显示WebView的WebView#setBackgroundColor或新加载页面的部分内容 在我看来,这意味着HTML已经加载(虽然不一定是任何其他资源),页面可能会开始呈现(但至关重要的是,在回调完成之前不会呈现) 我使用了以下代码:
public override void OnPageCommitVisible(WebView view, string url) {
view.EvaluateJavascript(_javascript, null);
base.OnPageCommitVisible(view, url);
}
而且它似乎工作正常。我希望这能帮助其他人。对于我的用例,答案似乎如下 onPageCommitVisible的Android文档()说明: 此回调可用于确定使回收的WebView可见的安全点,以确保不显示过时的内容。它在最早的时候被调用,可以保证WebView#onDraw不再从以前的导航中提取任何内容。下一个绘图将显示WebView的WebView#setBackgroundColor或新加载页面的部分内容 在我看来,这意味着HTML已经加载(虽然不一定是任何其他资源),页面可能会开始呈现(但至关重要的是,在回调完成之前不会呈现) 我使用了以下代码:
public override void OnPageCommitVisible(WebView view, string url) {
view.EvaluateJavascript(_javascript, null);
base.OnPageCommitVisible(view, url);
}
而且它似乎工作正常。我希望这对其他任何人都有帮助。您只需覆盖OnPageCommitVisible方法:
public override void OnPageCommitVisible(AWebView view, string url)
{
//Insert javascript injection first
view.EvaluateJavascript(_javascript, null);
base.OnPageCommitVisible(view, url);
}
它当然会开火。
有一个好的代码 您只需覆盖OnPageCommitVisible方法:
public override void OnPageCommitVisible(AWebView view, string url)
{
//Insert javascript injection first
view.EvaluateJavascript(_javascript, null);
base.OnPageCommitVisible(view, url);
}
它当然会开火。
有一个好的代码 通常,js是在OnPageFinished中注入的,您可以尝试注入js
view.EvaluateJavascript(_javascript,null)在OnPageStarted
OnPageFInished中的code>在所有场景中都不起作用-我尝试了,但没有起作用。我现在正在考虑是否需要保留两个Web视图,并在javascript完成后交换它们。但这似乎是浪费,我对一个浪费的解决方案不太满意在OnPageStarted
OnPageFInished中的code>在所有场景中都不起作用-我尝试了,但没有起作用。我现在正在考虑是否需要保留两个Web视图,并在javascript完成后交换它们。但这似乎是浪费,我对一个浪费的解决方案不太满意。这是我之前的回答,从2019年7月31日开始。这是我之前的回答,从2019年7月31日开始。