上一篇提到Windows Store协议的使用,其实Windows Store协议仅是系统内建的一种协议规则。咱们也能够本身定义一套规范的URI-Scheme,除了能够给其余App调用外,本应用也能够进行调用,解决一些特殊的场景,本讲具体探讨这一问题。html
关于Windows Store协议的解析和使用,可先阅读上一篇:http://www.cnblogs.com/zhxilin/p/4819372.html前端
前面提到,经过协议,应用能够被“激活(Activated)”,而且能够自行处理激活以后的操做。应用商店这个App的原理很简单,它在Package.appxmanifest里定义了一个“协议”类型的声明叫ms-windows-store,咱们能够模拟一下:web
因为ms-windows-store被定义为内建的协议,咱们自定义协议时并不能使用这个名称,这里用ms-windows-store1代替。windows
关于更多内建协议的使用规则,请参考:https://msdn.microsoft.com/en-us/library/windows/apps/mt228340.aspxapp
回到App.cs里,重载OnActivated方法,该方法接收一个IActivatedEventArgs类型的参数:async
1 protected override async void OnActivated(IActivatedEventArgs args) 2 { 3 // TODO: handle activate action 4 }
经过args参数的Kind属性来肯定具体是哪一种类型激活了应用,咱们这里只处理Protocol类型的激活(由于自定义协议就是一种Protocol):ide
1 protected override async void OnActivated(IActivatedEventArgs args) 2 { 3 if (args.Kind == ActivationKind.Protocol) 4 { 5 if (!_hasLaunched) 6 { 7 CreateRootFrame(); 8 _hasLaunched = true; 9 } 10 11 var protocalArgs = (ProtocolActivatedEventArgs) args; 12 if (protocalArgs.Uri.Scheme == AppConfig.MyAppScheme) 13 { 14 UrlSchemeHelper.ParseScheme(protocalArgs.Uri); 15 } 16 } 17 Window.Current.Activate(); 18 }
肯定了属于协议激活后,将args转成对应类型的参数ProtocolActivatedEventArgs,最终咱们如同处理一个普通http url同样,自定义个一个UrlSchemeHelper类进行解析和页面导航,具体处理请自行脑洞。函数
自定义协议,对呼叫协议做不一样的响应,这是一件很是酷的事情。不只能够给第三方应用调用,还能够给应用自己调用,处理一些特殊场景!我这里要说的一个特殊的适用场景就是App和Web页面的交互。url
App和Web页面的交互是很是广泛的情景,通常页面都会考虑直接使用脚本进行通知,而且我相信绝大部分前端开发者都已经被逼疯:WP须要一种处理,iOS又是另外一种处理;前端得判断请求来自什么平台,并且还不许确,BlaBla....总之问题很是多!spa
如今有这样一个需求,好比在一个Web页面里有一个按钮,触发了这个按钮以后要求App跳转到某一个指定页面,一般写个脚本的话应该是这样的(UWP应使用window.external.notify("")函数,且只能返回字符串)
1 function onNavigateClick() { 2 window.external.notify("navigate:some_page"); 3 }
App在WebView上注册void Browser_ScriptNotify(object sender, NotifyEventArgs e)事件,经过参数e.Value将web页面的通知内容“navigate:some_page”取出来作相应处理。
然而ScriptNotify事件的局限性很是大:
1.window.external.notify只能返回字符串
2.只有本地的Web页面(ms-appdata、ms-local-stream或ms-appx-web),或者受信任的HTTPS才能触发事件;普通HTTP没法触发
大多数Web页面都是HTTP的,而且若是下载到本地再显示每每有问题,所以对UWP来讲,这种交互方式简直就是噩梦!不只前端痛苦,客户端也痛苦!
这时候自定义协议就能够发挥其功力了!一样的例子,如今彻底能够改为协议的形式来进行通知:
1 function onNavigateClick() { 2 window.location.href = 'myapp://page?id=1&title=hero'; 3 }
App里就用上述提到的方式接收通知!
且慢,在UWP项目中,在一个WebView里,某一个html页面经过自定义的URI-Scheme的形式来通知APP时,WebView会触发一个UnsupportedUriSchemeIdentified事件,表示WebView并不认识这个协议,是否要处理取决于你。
UWP的WebView默认只能处理http, https, ms-appx-web和ms-local-stream这几种协议,对于其余协议,都会触发UnsupportedUriSchemeIdentified事件,而且会弹出一个警告对话框:
为了避免显示这个对话框,咱们须要手动处理一下:
1 private async void WebView_OnUnsupportedUriSchemeIdentified(WebView sender, WebViewUnsupportedUriSchemeIdentifiedEventArgs args) 2 { 3 args.Handled = true; 4 if (args.Uri.Scheme == AppConfig.MyAppScheme) 5 { 6 await Launcher.LaunchUriAsync(args.Uri); 7 } 8 }
先将args.Handled标记为true,警告对话框就不会弹出了;而后再经过Launcher尝试启动这个WebView不识别的URI;最后用咱们上述讲到的处理方式在App.OnActivated中接收并解析。
这样的好处彻底解放了前端开发的压力,这套机制适用于各类各样的客户端(iOS、Android、WP、Windows等);对于客户端而言,定义规范化的URI-Scheme有助于维护和扩展,甚至能够发展成开发平台或开放应用(如同商店APP同样)。