Xamarin.forms iOS WkWebView 在后台运行
Xamarin.forms iOS WkWebView runs in background
我有带有 EmbedIO 网络服务器的应用程序和 angular WebView 中带有 WkWebViewRenderer 的代码。 Angular 中的代码是轮询函数。
当应用程序进入后台时 DidEnterBackground
被调用并且我处理了网络服务器,但网络视图仍在运行。如何在触发此事件时使用 Angular 暂停 webview 以停止轮询,并在应用程序再次进入前台时再次启动它?
所以,我想出了一些解决方案来满足某些人的兴趣,我在我的应用程序中使用 AppShell 进行导航..
这是我的 EmbedIO 网络服务器助手 class:
public class WebServerHelper
{
private static readonly Lazy<WebServerHelper> lazy = new(() => new WebServerHelper());
public static WebServerHelper Instance => lazy.Value;
private CancellationTokenSource _cts;
private WebServer _webServer = null;
public void Run()
{
if(_webServer == null)
Task.Factory.StartNew(async () =>
{
using (_cts = new CancellationTokenSource())
using (_webServer = CreateWebServer())
{
await _webServer.RunAsync(_cts.Token);
}
});
}
public void Stop()
{
_cts.Cancel();
_cts = null;
_webServer = null;
}
private WebServer CreateWebServer()
{
var server = new WebServer(o => o
.WithUrlPrefix($"http://localhost:8080")
.WithMode(HttpListenerMode.EmbedIO))
.WithCors()
.WithLocalSessionManager()
.WithWebApi("/api", m => m
.WithController<TestController>()
...
.WithController<SystemController>())
.WithModule(new ActionModule("/", HttpVerbs.Any,
ctx => ctx.SendDataAsync(new { Message = "Error" })));
Trace.TraceInformation($"WebApi started on port: 8080");
server.OnUnhandledException += (s, e) => { Trace.TraceInformation("Unhadled Exception occured"); return Task.CompletedTask; };
server.OnHttpException += (s, e) => { Trace.TraceInformation("Http exception occured"); return Task.CompletedTask; };
return server;
}
}
然后我按照描述创建了混合网络视图here
这一切都在 AppDelegate 中运行,例如:
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
Forms.Init();
WebServerHelper.Instance.Run();
...
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
public override void WillTerminate(UIApplication application)
{
application.Dispose();
base.WillTerminate(application);
}
[Export("applicationWillEnterForeground:")]
public override void WillEnterForeground(UIApplication application)
{
//TODO: handle situation when user goes foreground (eg. double tap on start button and turn camera on)
WebServerHelper.Instance.Run();
((WKWebView)((HybridWebView)((WebContainer)((IShellSectionController)Shell.Current?.CurrentItem?.CurrentItem)?.PresentedPage).Content).GetRenderer().NativeView).GoForward();
}
[Export("applicationDidEnterBackground:")]
public override void DidEnterBackground (UIApplication application)
{
((WKWebView)((HybridWebView)((WebContainer)((IShellSectionController)Shell.Current?.CurrentItem?.CurrentItem)?.PresentedPage).Content).GetRenderer().NativeView).GoBack();
//In background task cancelation token is called dispose of webserver.
//This step obtain aditional (aprox.) 25 seconds to finish all ongoing operations.
application.BeginBackgroundTask(() => {
WebServerHelper.Instance.Stop();
});
}
我有带有 EmbedIO 网络服务器的应用程序和 angular WebView 中带有 WkWebViewRenderer 的代码。 Angular 中的代码是轮询函数。
当应用程序进入后台时 DidEnterBackground
被调用并且我处理了网络服务器,但网络视图仍在运行。如何在触发此事件时使用 Angular 暂停 webview 以停止轮询,并在应用程序再次进入前台时再次启动它?
所以,我想出了一些解决方案来满足某些人的兴趣,我在我的应用程序中使用 AppShell 进行导航..
这是我的 EmbedIO 网络服务器助手 class:
public class WebServerHelper
{
private static readonly Lazy<WebServerHelper> lazy = new(() => new WebServerHelper());
public static WebServerHelper Instance => lazy.Value;
private CancellationTokenSource _cts;
private WebServer _webServer = null;
public void Run()
{
if(_webServer == null)
Task.Factory.StartNew(async () =>
{
using (_cts = new CancellationTokenSource())
using (_webServer = CreateWebServer())
{
await _webServer.RunAsync(_cts.Token);
}
});
}
public void Stop()
{
_cts.Cancel();
_cts = null;
_webServer = null;
}
private WebServer CreateWebServer()
{
var server = new WebServer(o => o
.WithUrlPrefix($"http://localhost:8080")
.WithMode(HttpListenerMode.EmbedIO))
.WithCors()
.WithLocalSessionManager()
.WithWebApi("/api", m => m
.WithController<TestController>()
...
.WithController<SystemController>())
.WithModule(new ActionModule("/", HttpVerbs.Any,
ctx => ctx.SendDataAsync(new { Message = "Error" })));
Trace.TraceInformation($"WebApi started on port: 8080");
server.OnUnhandledException += (s, e) => { Trace.TraceInformation("Unhadled Exception occured"); return Task.CompletedTask; };
server.OnHttpException += (s, e) => { Trace.TraceInformation("Http exception occured"); return Task.CompletedTask; };
return server;
}
}
然后我按照描述创建了混合网络视图here
这一切都在 AppDelegate 中运行,例如:
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
Forms.Init();
WebServerHelper.Instance.Run();
...
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
public override void WillTerminate(UIApplication application)
{
application.Dispose();
base.WillTerminate(application);
}
[Export("applicationWillEnterForeground:")]
public override void WillEnterForeground(UIApplication application)
{
//TODO: handle situation when user goes foreground (eg. double tap on start button and turn camera on)
WebServerHelper.Instance.Run();
((WKWebView)((HybridWebView)((WebContainer)((IShellSectionController)Shell.Current?.CurrentItem?.CurrentItem)?.PresentedPage).Content).GetRenderer().NativeView).GoForward();
}
[Export("applicationDidEnterBackground:")]
public override void DidEnterBackground (UIApplication application)
{
((WKWebView)((HybridWebView)((WebContainer)((IShellSectionController)Shell.Current?.CurrentItem?.CurrentItem)?.PresentedPage).Content).GetRenderer().NativeView).GoBack();
//In background task cancelation token is called dispose of webserver.
//This step obtain aditional (aprox.) 25 seconds to finish all ongoing operations.
application.BeginBackgroundTask(() => {
WebServerHelper.Instance.Stop();
});
}