上一篇提到Windows Store协议的使用,其实Windows Store协议仅是系统内建的一种协议规则。我们也可以自己定义一套规范的URI-Scheme,除了可以给其他App调用外,本应用也可以进行调用,解决一些特殊的场景,本讲具体探讨这一问题。

关于Windows Store协议的解析和使用,可先阅读上一篇:http://www.cnblogs.com/zhxilin/p/4819372.html

一.自定义协议的处理

前面提到,通过协议,应用可以被“激活(Activated)”,并且可以自行处理激活之后的操作。应用商店这个App的原理很简单,它在Package.appxmanifest里定义了一个“协议”类型的声明叫ms-windows-store,我们可以模拟一下:

由于ms-windows-store被定义为内建的协议,我们自定义协议时并不能使用这个名称,这里用ms-windows-store1代替。

关于更多内建协议的使用规则,请参考:https://msdn.microsoft.com/en-us/library/windows/apps/mt228340.aspx

回到App.cs里,重载OnActivated方法,该方法接收一个IActivatedEventArgs类型的参数:

 protected override async void OnActivated(IActivatedEventArgs args)
{
// TODO: handle activate action
}

通过args参数的Kind属性来确定具体是哪种类型激活了应用,我们这里只处理Protocol类型的激活(因为自定义协议就是一种Protocol):

 protected override async void OnActivated(IActivatedEventArgs args)
{
if (args.Kind == ActivationKind.Protocol)
{
if (!_hasLaunched)
{
CreateRootFrame();
_hasLaunched = true;
} var protocalArgs = (ProtocolActivatedEventArgs) args;
if (protocalArgs.Uri.Scheme == AppConfig.MyAppScheme)
{
UrlSchemeHelper.ParseScheme(protocalArgs.Uri);
}
}
Window.Current.Activate();
}

确定了属于协议激活后,将args转成对应类型的参数ProtocolActivatedEventArgs,最终我们如同处理一个普通http url一样,自定义个一个UrlSchemeHelper类进行解析和页面导航,具体处理请自行脑洞。

二.自定义协议的意义

自定义协议,对呼叫协议作不同的响应,这是一件非常酷的事情。不仅可以给第三方应用调用,还可以给应用本身调用,处理一些特殊场景!我这里要说的一个特殊的适用场景就是App和Web页面的交互。

App和Web页面的交互是非常普遍的情景,一般页面都会考虑直接使用脚本进行通知,并且我相信绝大部分前端开发者都已经被逼疯:WP需要一种处理,iOS又是另一种处理;前端得判断请求来自什么平台,而且还不准确,BlaBla....总之问题非常多!

现在有这样一个需求,比如在一个Web页面里有一个按钮,触发了这个按钮之后要求App跳转到某一个指定页面,通常写个脚本的话应该是这样的(UWP应使用window.external.notify("")函数,且只能返回字符串)

 function onNavigateClick() {
window.external.notify("navigate:some_page");
}

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来说,这种交互方式简直就是噩梦!不仅前端痛苦,客户端也痛苦!

这时候自定义协议就可以发挥其功力了!同样的例子,现在完全可以改成协议的形式来进行通知:

 function onNavigateClick() {
window.location.href = 'myapp://page?id=1&title=hero';
}

App里就用上述提到的方式接收通知!

且慢,在UWP项目中,在一个WebView里,某一个html页面通过自定义的URI-Scheme的形式来通知APP时,WebView会触发一个UnsupportedUriSchemeIdentified事件,表示WebView并不认识这个协议,是否要处理取决于你。

UWP的WebView默认只能处理http, https, ms-appx-web和ms-local-stream这几种协议,对于其他协议,都会触发UnsupportedUriSchemeIdentified事件,并且会弹出一个警告对话框:

为了不显示这个对话框,我们需要手动处理一下:

 private async void WebView_OnUnsupportedUriSchemeIdentified(WebView sender, WebViewUnsupportedUriSchemeIdentifiedEventArgs args)
{
args.Handled = true;
if (args.Uri.Scheme == AppConfig.MyAppScheme)
{
await Launcher.LaunchUriAsync(args.Uri);
}
}

先将args.Handled标记为true,警告对话框就不会弹出了;然后再通过Launcher尝试启动这个WebView不识别的URI;最后用我们上述讲到的处理方式在App.OnActivated中接收并解析。

这样的好处完全解放了前端开发的压力,这套机制适用于各种各样的客户端(iOS、Android、WP、Windows等);对于客户端而言,定义规范化的URI-Scheme有助于维护和扩展,甚至可以发展成开发平台或开放应用(如同商店APP一样)。

【Win10 UWP】URI Scheme(二):自定义协议的处理和适用场景的更多相关文章

  1. URI Scheme注册伪协议实现远程命令执行

    Windows配置注册表注册伪协议 1.新建伪协议项 WIN+R 输入regedit 打开注册表,在注册表HKEY_CLASSES_ROOT键中新建一个项,项的名字就是你伪协议的名字,例如我注册一个c ...

  2. win10 uwp 入门

    UWP是什么我在这里就不说,本文主要是介绍如何入门UWP,也是合并我写的博客. 关于UWP介绍可以参见:http://lib.csdn.net/article/csharp/32451 首先需要申请一 ...

  3. 【Win10 UWP】URI Scheme(一):Windows Store协议的解析和使用

    协议是Windows Phone和Windows Store应用的一个重要特点,可以做到在不同应用之间进行互相呼起调用.小小协议,学问大着呢.我打算写几篇关于协议在UWP中使用的文章. 这一讲的主要对 ...

  4. 【Win10 UWP】QQ SDK(二):SDK的回调处理

    上一讲,我们介绍了QQ SDK的使用方法,请看<[Win10 UWP]QQ SDK(一):SDK基本使用方法> 一. 回调的基本形式 从前面的介绍中我们知道,我们的应用和QQ客户端之间需要 ...

  5. 在cef中使用自定义协议(scheme)

    在谷歌浏览器中点击设置,地址栏里出现的不是普通网址,而是chrome://settings/ 这个地址就是谷歌浏览器的自定义scheme,cef也提供了自定义协议手段.主要是通过 以下几步: 1.继承 ...

  6. 移动开发首页业界资讯移动应用平台技术专题 输入您要搜索的内容 基于Java Socket的自定义协议,实现Android与服务器的长连接(二)

    在阅读本文前需要对socket以及自定义协议有一个基本的了解,可以先查看上一篇文章<基于Java Socket的自定义协议,实现Android与服务器的长连接(一)>学习相关的基础知识点. ...

  7. 《精通并发与Netty》学习笔记(14 - 解决TCP粘包拆包(二)Netty自定义协议解决粘包拆包)

    一.Netty粘包和拆包解决方案 Netty提供了多个解码器,可以进行分包的操作,分别是: * LineBasedFrameDecoder (换行)   LineBasedFrameDecoder是回 ...

  8. JS魔法堂:Data URI Scheme介绍

    一.前言 上周五公司内部的Any Topic Conf.上我和同事们分享了这个主题,有同事说这个有用,有同事说这个没啥用,后来还延伸到网站性能的话题上,大家讨论的激烈程度让我觉得这次选题还不错.本篇先 ...

  9. Data URI Scheme,base64

    一.从HTTP URI Scheme入手 对于 <a href="http://github.com">HTTP URI Scheme</a> 我想大家都应 ...

随机推荐

  1. tomcat(三)--基本安装配置

    0x01  JDK和Tomcat安装 到oracle官网下载jdk,当前下载的版本是Linux x64 jdk-8u101-linux-x64.tar.gz 到apache官网下载tomcat,当前最 ...

  2. eval回显变量

    eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令.该命令适用于那些一次扫描无法实现其功能的变量. 一个应用场景如下: export path="/home/bin/" ...

  3. Ceph剖析:Paxos算法实现

    作者:吴香伟 发表于 2014/10/8 版权声明:可以任意转载,转载时务必以超链接形式标明文章原始出处和作者信息以及版权声明 Recovery阶段 在Leader选举成功后,Leader和Peon都 ...

  4. ue4 FPaths各目录

    GetWrappedLaunchDir() 启动时的工作目录,因为马上要把工作目录改为下面所说的exe所在目录,所以会先把当前的缓存起来 FPlatformProcess::BaseDir() 这个是 ...

  5. My English Dictionary

    A axis 坐标轴 architecture 结构 B C consider 考虑 closure  闭包 clip  修剪 convert 改变 D default 默认的 valid 有效的 d ...

  6. Linux下使用Eclipse开发Hadoop应用程序

    在前面一篇文章中介绍了如果在完全分布式的环境下搭建Hadoop0.20.2,现在就再利用这个环境完成开发. 首先用hadoop这个用户登录linux系统(hadoop用户在前面一篇文章中创建的),然后 ...

  7. 关于“float”的一次探索--遇到了一个span元素可以设置宽高引发的思考

    起初,这个问题和float还有设置宽高之间是没有任何关联的,一开始这是一个关于height和line-height的问题,目的是为了探究一下这两者之间的关系,但是在学习的过程中,我翻之前写的代码,发现 ...

  8. iOSview整体上移下移(点击键盘)

    首先创建一个textFiled 并实现起代理方法 - (void)textFieldDidBeginEditing:(UITextField *)textField { //设置动画的名字 [UIVi ...

  9. C语言打印最长字符串

    编程在一个已知的字符串中找最长单词,假定字符串中只含字母和空格,空格用来分隔不同单词. ]; printf("请输入字符串:"); fgets(p, , stdin); ; ; ; ...

  10. java线程池初步理解

    多线程基础准备 进程:程序的执行过程,持有资源和线程 线程:是系统中最小的执行单元,同一个进程可以有多个线程,线程共享进程资源 线程交互(同步synchronized):包括互斥和协作,互斥通过对象锁 ...