使用安卓直达号可以查询到什么信息?

安 卓 直 达 号 的代 理 商 怎 么 查 询?_百度知道
安 卓 直 达 号 的代 理 商 怎 么 查 询?
我有更好的答案
查询可以到官方网站;打开网站后,点击导航栏的代理商查询按钮即可
1条折叠回答
为您推荐:
其他类似问题
您可能关注的内容
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。手机上的安卓直达号怎么使用?_百度知道
手机上的安卓直达号怎么使用?
我有更好的答案
如果手机需要下载安装软件应用,建议尝试:1.使用手机功能表中自带的浏览器上网,直接搜索需要的软件进行下载安装(下载安卓版本格式为apk)。2.使用电脑下载APK格式的安装包,连接数据线传输至手机,操作手机在应用程序-我的文件中找到安装包,运行后点击安装按钮。3.下载完成后点击下载的应用,根据软件手机界面中软件安装提示点击安装即可。
三星产品问答服务
主营:电子产品
从手机上打开黄页,在搜索框中输入你要查询的关键字。
百度的入口对接到淘宝手机H5网页
为您推荐:
其他类似问题
您可能关注的内容
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。安卓直达号好用吗?有谁用过安卓直达号?_百度知道
安卓直达号好用吗?有谁用过安卓直达号?
我有更好的答案
好用啊,信息比较准确,能够查询带你想要的商家信息,比如电话。地址。是做什么的。可信度等等..是手机黄页里面的搜索功能。希望可以帮到你哦
为您推荐:
其他类似问题
您可能关注的内容
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。&figure&&img src=&https://pic4.zhimg.com/v2-ffad4fc095ac_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&https://pic4.zhimg.com/v2-ffad4fc095ac_r.jpg&&&/figure&&p&先划重点:&b&字符串在最终输出前调用 Number 方法来扁平化,可以提高后续操作的性能。&/b&&/p&&p&&br&&/p&&p&先从一段 benchmark 开始说起:&/p&&p&setup block:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&kd&&function&/span& &span class=&nx&&makeExpoStr&/span&&span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&kd&&var&/span& &span class=&nx&&s&/span& &span class=&o&&=&/span& &span class=&s2&&&a&&/span&&span class=&p&&;&/span&
&span class=&k&&for&/span& &span class=&p&&(&/span&&span class=&kd&&var&/span& &span class=&nx&&i&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span& &span class=&nx&&i&/span& &span class=&o&&&&/span& &span class=&mi&&12&/span&&span class=&p&&;&/span& &span class=&nx&&i&/span&&span class=&o&&++&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&nx&&s&/span& &span class=&o&&+=&/span& &span class=&nx&&s&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&k&&return&/span& &span class=&nx&&s&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&case 1:直接读入 Buffer(无 Number 操作)。&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&//env: Node.js&/span&
&span class=&kd&&var&/span& &span class=&nx&&str&/span& &span class=&o&&=&/span& &span class=&nx&&makeExpoStr&/span&&span class=&p&&();&/span&
&span class=&nx&&Buffer&/span&&span class=&p&&.&/span&&span class=&nx&&from&/span&&span class=&p&&(&/span&&span class=&nx&&str&/span&&span class=&p&&);&/span&
&/code&&/pre&&/div&&p&case 2:Number 操作后再读入 Buffer(存在 Number 操作)。&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&//env: Node.js&/span&
&span class=&kd&&var&/span& &span class=&nx&&str&/span& &span class=&o&&=&/span& &span class=&nx&&makeExpoStr&/span&&span class=&p&&();&/span&
&span class=&nb&&Number&/span&&span class=&p&&(&/span&&span class=&nx&&str&/span&&span class=&p&&);&/span&
&span class=&nx&&Buffer&/span&&span class=&p&&.&/span&&span class=&nx&&from&/span&&span class=&p&&(&/span&&span class=&nx&&str&/span&&span class=&p&&);&/span&
&/code&&/pre&&/div&&p&通过测试发现存在 Number 操作(case #2)的比直接读入(case #1)的效率高 2.8x 左右。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-b8ee6efa7615f_b.jpg& data-rawwidth=&651& data-rawheight=&62& class=&origin_image zh-lightbox-thumb& width=&651& data-original=&https://pic4.zhimg.com/v2-b8ee6efa7615f_r.jpg&&&/figure&&p&(条状图越长,性能越高)&/p&&p&要解释这个现象,首先先要了解 makeExpoStr 返回的字符串组成。&/p&&p&通过上一章 &a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&《技淫巧学 V8 之六,字符串在 V8 内的表达》&/a& 我们了解到: V8 为了提升字符串拼接时的性能采用 ConsString 来表达拼接后的字符串。故 makeExpoStr 返回的字符串是由 ConsString 组成的多层树形结构(&a href=&https://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Rope_%28data_structure%29& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Rope Structure&/a&)。&/p&&p&而&b&采用 ConsString 虽然提升了字符串在拼接时的性能,但对其进行操作(如字符的访问等)的复杂度就会变高(特别是有存在大量拼接时)。&/b&&/p&&p&在实际应用过程中,字符串的生命周期可以粗略的划分为以下两个阶段:&/p&&ul&&li&构造期,使用 ConsString 提升多次拼接时的性能。&/li&&li&使用期(如访问读取等),使用 SeqString 降低字符串访问的复杂度。&/li&&/ul&&p&当字符串进行特定操作(如 CharAt )时, V8 会假设后续可能在此字符串上还有更多(类似的)操作,故此字符串由构造期进入使用期,V8 将多层 ConsString 拷贝(扁平化)为 SeqString 以降低后续访问的复杂度,这种过程我们将其称为 FlattenString。&/p&&blockquote&非 ConsString 表达的字符串一定是扁平(Flat)的,ConsString(SeqString, empty_string)
所表达的字符串也可认为是扁平(Flat)的。&/blockquote&&p&&br&&/p&&p&在开发调试过程中,可以调用 V8 的 Runtime Call (%FlattenString)来强制扁平化字符串。&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// flags: --allow-natives-syntax&/span&
&span class=&kd&&var&/span& &span class=&nx&&name&/span& &span class=&o&&=&/span& &span class=&s2&&&I am &&/span& &span class=&o&&+&/span& &span class=&s2&&&superzheng&&/span&&span class=&p&&;&/span&
&span class=&c1&&// name = ConsString(&I am &, &superzheng&)&/span&
&span class=&o&&%&/span&&span class=&nx&&FlattenString&/span&&span class=&p&&(&/span&&span class=&nx&&name&/span&&span class=&p&&);&/span&
&span class=&c1&&// name = ConsString(&I am superzheng&, &&)&/span&
&/code&&/pre&&/div&&p&&br&&/p&&p&而在&b&运营环境中,通过如下的字符串操作&/b&(让 V8 认为此字符串进入使用期)&b&来隐式扁平化:&/b&&/p&&ul&&li&转换为数值(Number / parseInt / ~ )&/li&&li&读取字符(s[0] / charCodeAt )&/li&&li&正则表达式操作( test / exec )&/li&&/ul&&p&在这些操作中,&b&Number 的性能最高&/b&,所以在实际应用中一般采用 Number 方法的 side effects 来隐式扁平化字符串。&/p&&p&&i&请注意:频繁的扁平化操作会严重影响性能,故应仅在字符串最终输出(调用外部代码,如 Buffer.from)时进行。&/i&&/p&&blockquote&&i&要不然 V8 也不用 ConsString 来表达拼接后的字符串了。&/i&&/blockquote&&p&这里有一个工程化技巧,不应在代码中直接使用 Number,而应将 Number 包装成为方法(或使用现成模块如 &a href=&https://link.zhihu.com/?target=https%3A//github.com/davidmarkclements/flatstr& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&flatstr&/a&),以防对于代码的误解(认为无用代码而造成误删除)同时也便于全局更新。&/p&&p&&br&&/p&&p&而在外部 C/C++ 代码(如 Node.js)调用 v8::String::Write 方法拷贝字符串内容时,(如外部代码认为此字符串可能被拷贝多次)可指定拷贝选项 HINT_MANY_WRITES_EXPECTED ,V8 会将传入的字符串扁平化以降低后续拷贝消耗。&/p&&blockquote&V8 希望屏蔽内部实现对于开发者的影响,所以对外(不仅 JavaScript 层面,甚至提供给 C/C++ 调用的接口)并没有扁平化字符串的概念。&br&取而代之的是针对不同的场景有着不同意义的选项(flags)。&/blockquote&&p&文章开头例子中的代码在调用 Buffer.from(也就是 Node.js C++ 调用 StringBytes::Write) 时,Node.js 指定了多次拷贝选项(HINT_MANY_WRITES_EXPECTED),此时 V8 中 Write 方法会先将字符串扁平化后再进行拷贝,如下图所示:&/p&&figure&&img src=&https://pic3.zhimg.com/v2-1fa106cb9_b.jpg& data-rawwidth=&835& data-rawheight=&224& class=&origin_image zh-lightbox-thumb& width=&835& data-original=&https://pic3.zhimg.com/v2-1fa106cb9_r.jpg&&&/figure&&p&&br&&/p&&p&这里存在一个非常大的疑问:&/p&&p&既然(Node.js)Buffer.from 也会要求 V8 将字符串扁平化与调用 Number 隐式扁平化的作用是完全一样的,所以理论上不应有任何的性能提升。&/p&&p&但在实际测试中确实存在有 2.8x 倍的差距!这到底是差在哪里了?&/p&&p&这里先要肯定之前分析(方向)是正确的,而问题就出在 Node.js 默认字符编码 UTF-8 上。&/p&&blockquote&&a href=&https://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/UTF-8& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&UTF-8&/a& 是一种针对 Unicode 的可变长度字符编码。&br&字符基本范围是 1 ~ 3 字节,Unicode6.1 范围是 1 ~ 4 字节, UCS-4 范围是 1 ~ 6 字节(废弃)。&/blockquote&&p&Node.js 默认采用 UTF-8 字符编码,从而导致&b&当字符串以 UTF-8 表达时所占用的空间不能直接通过字符数(线性)计算得到,需要遍历每个字符(cons-part)才可得到&/b&。&/p&&p&调用 Buffer.from (默认编码 UTF-8)时,Node.js C++ 调用 v8::String::Utf8Length 获得字符串以 UTF-8 表达时所需的空间大小,并在空间分配后传递给 v8::String::WriteUtf8 写入字符串,过程如下图所示:&/p&&figure&&img src=&https://pic3.zhimg.com/v2-1dc29d387bceb9cff90751_b.jpg& data-rawwidth=&860& data-rawheight=&166& class=&origin_image zh-lightbox-thumb& width=&860& data-original=&https://pic3.zhimg.com/v2-1dc29d387bceb9cff90751_r.jpg&&&/figure&&p&当字符串以多层 ConsString 表达时,存在有两个热点函数:&/p&&ul&&li&计算所需空间大小的遍历(v8::String::Utf8Length)&/li&&li&读取拷贝的遍历(v8::String::WriteUtf8)&/li&&/ul&&p&所以将字符串在传入(Buffer.from)前先行扁平化,可以减轻两个热点函数消耗以提升性能。&/p&&p&&br&&/p&&p&讲到这里我们了解到,开头例子中的性能差距主要由 UTF-8 编码特性引发。如果将其换为 ASCII 编码是否就可以规避这个问题(而不需使用奇技淫巧)?&/p&&p&case 3:以 ASCII 编码读入 Buffer 。&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// env: Node.js&/span&
&span class=&kd&&var&/span& &span class=&nx&&str&/span& &span class=&o&&=&/span& &span class=&nx&&makeExpoStr&/span&&span class=&p&&();&/span&
&span class=&nx&&Buffer&/span&&span class=&p&&.&/span&&span class=&nx&&from&/span&&span class=&p&&(&/span&&span class=&nx&&str&/span&&span class=&p&&,&/span& &span class=&s2&&&ascii&&/span&&span class=&p&&);&/span&
&/code&&/pre&&/div&&p&通过测试我们发现 ASCII 编码(case #3)比 UTF-8 编码(case #1)的读入性能高 6x 倍左右,甚至比扁平化后以 UTF-8 编码读入(case #2)的性能还要高 2.8x 倍左右。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-cd02acee7be5ffc3b24d_b.jpg& data-rawwidth=&651& data-rawheight=&98& class=&origin_image zh-lightbox-thumb& width=&651& data-original=&https://pic2.zhimg.com/v2-cd02acee7be5ffc3b24d_r.jpg&&&/figure&&p&(条状图越长,性能越高)&/p&&p&&br&&/p&&p&总结一下:&/p&&ul&&li&&b&拼接后的字符串,在最终输出前调用 Number 方法进行隐式扁平化,可以提高后续操作的性能。&/b&&/li&&li&当字符串以 UTF-8 表达时,需要遍历每个字符才可得到其所占用的空间大小。&/li&&/ul&&p&&b&只有了解奇技淫巧背后的原理,才能举一反三,甚至会发现更优美、更高效的解决方案。&/b&&/p&&p&&br&&/p&&p&欢迎收看下一章:&/p&&ul&&li&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&奇技淫巧学 V8 之六,字符串在 V8 内的表达&/a&&/li&&li&奇技淫巧学 V8 之七,字符串的扁平化(当前章节)&/li&&li&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&奇技淫巧学 V8 之八,常量字符串&/a&(下一章)&/li&&/ul&&p&&br&&/p&&p&奇技淫巧学 V8 对象(JSObject)部分章节:&/p&&ul&&li&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&奇技淫巧学 V8 之一,对象访问模式优化&/a&&/li&&li&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&奇技淫巧学 V8 之二,对象在 V8 内的表达&/a&&/li&&li&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&奇技淫巧学 V8 之三,多态内联缓存 PICs&/a&&/li&&li&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&奇技淫巧学 V8 之四,迁移对象至快速模式&/a&&/li&&li&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&奇技淫巧学 V8 之五,对象属性的快速删除&/a&&/li&&/ul&
先划重点:字符串在最终输出前调用 Number 方法来扁平化,可以提高后续操作的性能。 先从一段 benchmark 开始说起:setup block:function makeExpoStr() {
var s = "a";
for (var i = 0; i & 12; i++) {
}case 1:直接读入 Buffe…
&p&最近 &a class=&member_mention& href=&http://www.zhihu.com/people/4866fceb246d9ea621fd5& data-hash=&4866fceb246d9ea621fd5& data-hovercard=&p$b$4866fceb246d9ea621fd5&&@大漠穷秋&/a& 发布了一篇&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&对比 Angular 和 Vue 的文章&/a&。框架之间的对比虽然是老生常谈,但也确实是绕不过去的话题,Vue 本身的文档里也直接就有和其他框架的对比。同为开源的技术方案,比较本身其实没有任何问题,但在写 Vue 与其他框架的比较的时候,我们尽力做到两点:&/p&&p&1. 确保事实的准确性。有的就是有,没有就是没有,不确定的就不说,弄错了一定改。&/p&&p&2. 确保语气的中立性。别人的缺点指出但不嘲讽,优点大方承认。&/p&&p&之前 @汪志成 对 Vue 跟 Angular 的比较文案提出了意见,我们也对应地进行了修订。也欢迎社区继续进行监督和反馈 —— 比较的目的不是扭曲大家的认知,而是为了帮助大家做出自己的判断。&/p&&p&现在说回来大漠(后面都用大漠指代,注意跟 w3cplus &a class=&member_mention& href=&http://www.zhihu.com/people/5fbc10cabdc95d7f30d08& data-hash=&5fbc10cabdc95d7f30d08& data-hovercard=&p$b$5fbc10cabdc95d7f30d08&&@大漠&/a& 老师不是一个人,对不住了哈哈)的这篇文章,很遗憾,以上两点都不及格。&/p&&p&先说事实。&/p&&p&&br&&/p&&h2&CLI/工具链&/h2&&p&首先两个框架 CLI 的定位不一致。vue-cli 不是一个打包工具,它只是一个 scaffold,也就是初始化工具。真正负责打包的是初始化之后项目内的 webpack 配置和 npm 脚本。从一开始 vue-cli 就是这样的设计意图,项目真正的工具链在项目模板里面而不是 CLI 里面。&/p&&p&相比之下 @angular/cli 是一个全包式的命令行工具,一切都是通过 `ng` 来执行,但这不代表 `ng` 有的命令 Vue 就没有对应的功能 —— 比如在 vue-cli 生成的项目里面:&/p&&ul&&li&npm run dev 对应 ng serve&/li&&li&npm run build 对应 ng build&/li&&li&npm run lint 对应 ng lint&/li&&li&npm run unit 对应 ng test&/li&&li&npm run e2e 对应 ng e2e&/li&&/ul&&p&除了 i18n 之外,@angular/cli 有的 Vue 都有。『很多日常开发必备的功能都需要开发者自己去下载配置第三方的Node模块』这句话是一个事实上的错误。看起来大漠连 vue-cli 生成的项目都没跑过就急着写文章了呢。&/p&&p&其次,CLI 命令/参数多 = 更优秀?并没有这样的道理,create-react-app 估计要哭晕在厕所了。如果我们仔细看看文中的截图,ng build 的多个参数,其实就是对应不同的底层 webpack 配置。说实话,我相信不仅仅是我,对于很多其他开发者而言,更宁可直接阅读 webpack 的文档来调整真正的 webpack 配置(并且可以 commit 进项目),而不是去额外学习一套由 Angular 封装的抽象,因为实际生产中需求千变万化,完全被 CLI 封装的配置不利于二次开发。&/p&&p&实事求是地说,@angular/cli 确实有一些值得学习的地方,比如 ng serve 对 SSL 的支持。我们也会在新版本的 vue-cli 中持续吸收改进,但连 vue-cli 能做什么都没弄清楚就拿玩具来打比方,只能贻笑大方了。&/p&&p&&br&&/p&&h2&异步加载模块&/h2&&p&我不知道为什么大漠又截了个不知哪里的旧中文文档的图,还没截全 —— 最新的关于异步加载的文档是下面这两个链接:&/p&&ul&&li&&a href=&http://link.zhihu.com/?target=https%3A//cn.vuejs.org/v2/guide/components.html%23%25E5%25BC%%25AD%25A5%25E7%25BB%%25BB%25B6& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&文档中关于异步组件的部分&/a&&/li&&li&&a href=&http://link.zhihu.com/?target=https%3A//router.vuejs.org/en/advanced/lazy-loading.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&路由文档关于路由懒加载的部分&/a&&/li&&/ul&&p&Vue 将一个组件(以及其所有依赖)改为异步加载,所需要的只是把:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&import Foo from './Foo.vue'
&/code&&/pre&&/div&&p&改成&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&const Foo = () =& import('./Foo.vue')
&/code&&/pre&&/div&&p&就这么简单。这里注意三点:&/p&&ol&&li&当这样分割的时候,该组件所依赖的其他组件或其他模块都会自动被分割进对应的 chunk 里,不存在大漠所暗示的『手动改 500 个组件』这样的情况。况且两边代码分割的功能都是 webpack 提供的,我真不知道大漠是真的不懂还是故意误导。&/li&&li&所谓的路由级别的分割,只需要把这个组件作为路由组件就可以了,甚至连路由配置表都不用改。&/li&&li&更重要的是这样的异步组件并不一定只能用在路由层面 —— 任何你要用到一个组件的地方,都可以用异步组件无缝替换之,这种灵活性是 Angular 的 loadChildren 根本无法比拟的。比如一个动态的长表单页面,你甚至可以根据用户目前的输入来动态抓取表单接下来的部分(这个用例还是 wepback 的维护者 Sean Larkin 发现并用在生产中的)。&/li&&/ol&&p&&br&&/p&&h2&单元测试和集成测试&/h2&&blockquote&Vue的单元测试需要你自己去安装配置 Karma + Jasmine&/blockquote&&p&—— 事实错误。vue-cli 的 webpack 模板内置了开箱即用的 Karma + Jasmine 配置,自带了一个初始测试用例,npm run unit 即可。这又双一次证明大漠根本没有跑过 vue-cli 生成的项目。&/p&&p&Vue 的单测不仅仅支持 Karam + Jasmine - 事实上社区有广泛的单测反馈,对于 Jest, Ava 都有实践,我们正在开发中的官方的单测工具库 vue-test-utils (由社区最流行的单测库 avoriaz 的开发者开发)会进一步简化常见的组件单测断言需求,并且还会有和所有主流 test runner 的整合指南。&/p&&blockquote&在集成测试方面,Vue就只能是0分了,因为压根什么都没做。&/blockquote&&p&—— again,事实错误。vue-cli 的 webpack 模板内置了开箱即用的 Nightwatch + Selenium E2E 测试配置,自带了一个初始测试用例,npm run e2e 即可。这又双叒一次证明大漠根本没有跑过 vue-cli 生成的项目。&/p&&blockquote&从对集成测试的支持大家应该可以看出来,在那些技术含量不太高的地方,Vue确实可以抄袭得有模有样,但是一旦技术门槛提高,Vue就没法抄了,或者说抄得没那么快了。&/blockquote&&p&—— 集成测试这种东西,有什么技术门槛可言,还需要抄么?顺便说一句,vue-cli 初始化的项目可是早比 @angular/cli 正式发布前就已经自带集成测试了...&/p&&p&&br&&/p&&h2&TypeScript&/h2&&p&原文直接说了说 TypeScript 有多好,言下之意这是只有 Angular 才有的东西?事实上:&/p&&ul&&li&Vue 全家桶自 2.0 发布起就自带官方 TypeScript typing;&/li&&li&Vue 有官方的 &a href=&http://link.zhihu.com/?target=https%3A//github.com/vuejs/vue-class-component& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TypeScript component class decorator&/a&;&/li&&li&有非常多在生产环境中使用 Vue + TS 组合的用户;&/li&&li&VSCode + &a href=&http://link.zhihu.com/?target=https%3A//vuejs.github.io/vetur/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Vetur&/a& 插件提供完美的 IDE 类型提示;&/li&&li&&a href=&http://link.zhihu.com/?target=https%3A//github.com/vuejs/vue/pull/5887& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TS 团队非常积极地和 Vue 合作推动更好的 Vue + TS 体验&/a&,下个版本的 Vue 甚至不需要用 class decorator 也能获得完善的类型推导。&/li&&/ul&&p&这里我不否认 Angular 是一个 TS 为主导的框架,所以默认的 workflow 跟 TS 的整合会更紧密,但单说 TS 配置完成后的开发体验,并不构成本质的差别。&/p&&p&&br&&/p&&h2&AOT & Treeshaking&/h2&&blockquote&随着你的项目规模越来越大,你会越来越体会到有AOT是多么的重要,而Vue在这一点上根本无能为力,开发者只能自求多福了。&/blockquote&&p&—— again,事实错误。Vue 从 2.0 一开始就对模板编译策略进行了专门的设计:框架本身的 dist 文件分为包含编译器和不包含编译器的版本,前者可以直接在浏览器里编译,后者则专门用于构建时 AOT 编译,并且剥去了编译器所占的尺寸。vue-cli 初始化的项目默认就是 AOT 的状态 —— 请注意,从 Vue 2.0 快一年前发布的时候就已经是这样了,早于 @angular/cli 支持 AOT 的时间。&/p&&p&Vue 在构建时还有很多其他优化,细节可以看&a href=&http://link.zhihu.com/?target=https%3A//docs.google.com/presentation/d/1ot0JYflhGmPq5Y_PAIEEyYH4APWBK17Zf7-d1dM4v7g/edit%3Fusp%3Dsharing& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&我 7 月在 JSConf 演讲&/a&的末尾部分。&/p&&p&再说说 Treeshaking。上面的 slides 里面也有提到 Treeshaking 的原理,这里谈几点:&/p&&ol&&li&直到 webpack 3.3 之前,treeshaking 都依赖 rollup。框架本身层面,Vue 的 dist 文件就是用 rollup 打包的 flat ES module(注意,这又是一个 Vue 2.0 发布时就采用的设计,React 后来也采用了同样的构建,而 Igor Minar 提到过 Angular 也想采用同样的发布构建),保证了框架本身尺寸的最小化。&/li&&li&应用层面的 Treeshaking,@angular/cli 也是要用 rollup 才能达成,而 webpack 3.3 之后终于支持真正的 treeshaking(文档里叫 scope hoisting)—— 任意使用 webpack 的项目只要启用 ModuleConcatenationPlugin 就可以获得 类似 rollup treeshaking 的效果。对于 vue-cli 的模板来说,默认启用就是举手之劳,现阶段只是希望等这个功能更稳定一些。&/li&&/ol&&p&&br&&/p&&h2&团队&/h2&&p&我很早就说过了,用『一个人』来贬低一个项目是很短视的行为。Ruby 最早只有 Matz,Python 最早只有 Guido,Linux 最早只有 Linus,任何项目,尤其是独立开源项目,都有一个发展的过程。有爹如 Angular 1,下场又如何呢?&/p&&p&Vue 的 contributor graph 有一些细节,不说估计很容易就被忽略了。2.0 的代码在初始开发阶段只有我一个人写,所以绝大部分早期的 commit 都是我的,而且保留了所有细粒度的 commit,比如改个缩进啥的。到后期正式发布之后,commit 就开始强调可读性,一个 feature 一般都是 rebase 成几个比较阶段性的 commit,大部分 PR 也都是 squash 成了一个单独的 commit,所以 contributor 的 commit 会偏少。&/p&&p&还是用数据说话。如果只看近期的状态,&a href=&http://link.zhihu.com/?target=https%3A//www.javascripting.com/view/vue& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&这个网站&/a&有个指标挺有意思:最近的 100 个 commit 来自多少个 contributor?&/p&&p&Vue 是 23 个,Angular 是 38 个。Angular 更多,但很明显 Vue 也绝不是只有我一个人。&/p&&p&&br&&/p&&h2&结语&/h2&&p&说了这么多,我们可以看到原文里几乎每一个技术比较点都经不起推敲,并且可以很明显的看出,作者对于 Vue 生态缺乏足够的了解,为了贬低而贬低的意图太过明显,甚至把一些在 Vue 当中更早落地的技术细节看做是在抄袭 Angular...&/p&&p&在我以前的一个回答中 (&a href=&https://www.zhihu.com/question//answer/& class=&internal&&尤雨溪:什么才是你心目中的前端圈?&/a&) 我说过希望中文前端圈能少一些戾气,所以我这里尽量只谈技术上的事实,并且:&/p&&p&&b&希望 Vue 的用户和支持者不要对大漠或 Angular 进行不理性的攻击。&/b&&/p&&p&&b&希望 Vue 的用户和支持者不要对大漠或 Angular 进行不理性的攻击。&/b&&/p&&p&&b&希望 Vue 的用户和支持者不要对大漠或 Angular 进行不理性的攻击。&/b&&/p&&p&重要的话说三遍。这篇文章不是为了撕逼,只是为了澄清一些技术上的事实。对自己要求更高一点的同学,可以不要站队。把自己跟一个框架捆绑不是什么好事,你的自信应该来自于你驾驭框架的能力,而不是被框架驾驭的能力。&/p&&p&&br&&/p&&p&大漠在另一个回答下面(&a href=&https://www.zhihu.com/question//answer/& class=&internal&&知乎用户:为什么vue的高仿项目层出不穷,而React和angular却很少?&/a&) 也写过这样的一段话:&/p&&blockquote&我曾经问过我的老板和Angular团队的负责人这样一个问题:在中国国内的网络上经常出现针对Angular的讨论,有一些内容非常偏激,甚至可以说【恶毒】,作为Angular在国内推广的负责人,我可以去和这些人针锋相对吗?我的老板是这样跟我说的:“战胜”竞争对手不是Angular团队的目标,我们的目标是帮助开发者和企业更好地开发面向未来的WEB应用。很平常的一句话,但是给我留下的印象非常深刻,因为我看到了一个全新的角度,原来他们是这样去思考问题的。反观国内的很多技术讨论区,很多情况下会非常快速地陷入人身攻击和胡扯的境地,给人的感觉就像泼妇骂街一样。尤其是前端社区,越来越像娱乐圈。所有的参与者,包括提问题的人,请你们安静一秒钟,仔细想想,你自己想要什么?在口水战中战胜对手能帮助你提高编码技巧,还是能帮助你提高认识世界的高度?&/blockquote&&p&在那个充满戾气的问题下面看到这样一段话,当时我是很佩服大漠的。然而... 现在这两篇文章,真让我怀疑大漠是被人盗号了...&/p&&p&如果你没有被盗号,摸着你的良心问问,你,脸不脸红?&/p&&p&&br&&/p&&p&---&/p&&p&注:为了避免站队撕逼,设置为只有我关注的人可以评论了,支持 Vue 的同学点个赞即可,谢谢。&/p&
发布了一篇。框架之间的对比虽然是老生常谈,但也确实是绕不过去的话题,Vue 本身的文档里也直接就有和其他框架的对比。同为开源的技术方案,比较本身其实没有任何问题,但在写 Vue 与其他框架的比较的时候,我们…
&figure&&img src=&https://pic1.zhimg.com/v2-0e8d910bb1d89aac4ba69d_b.jpg& data-rawwidth=&1300& data-rawheight=&600& class=&origin_image zh-lightbox-thumb& width=&1300& data-original=&https://pic1.zhimg.com/v2-0e8d910bb1d89aac4ba69d_r.jpg&&&/figure&这是Kotlin开发系列文章的第三篇,也是最后一篇。在前面的两篇文章中,我们探索了如何使用Kotlin来进行部分实用Android开发工作。如果你没有看过,建议可以先看一下:&br&&br&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&实战Kotlin@Android(一):项目配置和语言转换&/a&&br&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&实战Kotlin@Andorid(二):界面构建与扩展方法&/a&&br&&blockquote&&i&版权声明&br&原作者:Doug Stevenson&br&译者:程大治&br&本文由原作者授权翻译并发布,首发于移动开发前线公众号,未经允许禁止转载。&/i&&/blockquote&&br&&p&到现在,我们已经可以使用比XML更少的代码完成View的构建,更别说Java了。Kotlin的语法为声明式,View之间的嵌套也十分清晰,而且我们还可以给类很方便地添加实用方法。&/p&&p&但在上一篇的结尾我们提到要给View设置左内边距并不容易实现。如果硬是要用Kotlin做这件事,就需要如下编码,注意其中我们需要调用setPadding()并传入四个参数,而不是给一个由JavaBean风格的getter/setter生成的模拟属性赋值。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-81f9bf02a40d5d47e42407bebd3c1a0d_b.jpg& data-rawwidth=&569& data-rawheight=&139& class=&origin_image zh-lightbox-thumb& width=&569& data-original=&https://pic1.zhimg.com/v2-81f9bf02a40d5d47e42407bebd3c1a0d_r.jpg&&&/figure&&p&为了使构建View的代码风格一致,我们更愿意直接给左内边距赋值,而不是调用有四个参数的方法。你可能想到给View类添加一个扩展方法setleftPadding(int)。这样做OK,但是你无法通过lambda with receiver这样写:leftPadding = dp_i(16),原因是由Kotlin生成的长相类似JavaBean的方法不会生成模拟变量,只有Java类中的成员方法可以。&/p&&p&但是,Kotlin可以定义扩展属性,长得和Java类与方法中的变量差不多。一个扩展变量会像Kotlin扩展方法一样被移植到存在的类中,所以可以直接通过该类实例访问,只需你在代码中导入扩展变量。&/p&&p&我们可以定义一个扩展变量使得对于左内边距的设置代码能和其他属性设置代码风格一致。下面的代码设置了左内边距,其他类似:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-b3c14f8d64d47cbf4f9591_b.jpg& data-rawwidth=&609& data-rawheight=&280& class=&origin_image zh-lightbox-thumb& width=&609& data-original=&https://pic4.zhimg.com/v2-b3c14f8d64d47cbf4f9591_r.jpg&&&/figure&&p&所以TextView就可以这样创建了:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-39d193dee4bfef1c17007a_b.jpg& data-rawwidth=&564& data-rawheight=&141& class=&origin_image zh-lightbox-thumb& width=&564& data-original=&https://pic4.zhimg.com/v2-39d193dee4bfef1c17007a_r.jpg&&&/figure&&p&所有属性的设置代码风格变一致了,棒!&/p&&p&对于padLeft扩展属性有如下几点需要注意:&/p&&ul&&li&&p&扩展属性的注解是class dot property,注意与扩展方法的class dot function注解区别开。&/p&&/li&&li&&p&扩展属性的类型在冒号后指定。&/p&&/li&&li&&p&通过var关键字声明,这也是Kotlin中声明可变变量的关键字,也就是可以直接赋值。如果要声明不可变的只读变量则使用val关键字。&/p&&/li&&li&&p&一个可变的扩展属性需要我们同时提供getter和setter的实现。&/p&&/li&&/ul&&p&padLeft的setter方法的实现基于View的setPadding()方法,它接收赋值语句右边的值作为第一个参数传入,并传入TextView的其他内边距属性的值。getter方法的实现只不过将View内部的左内边距属性返回。&/p&&p&小吐槽:Android的View类给内边距属性提供了JavaBean风格的getter方法,却没有提供setter方法,现在通过Kotlin我们化解了这个尴尬。&/p&&p&如果你觉得现有的哪个不可修改的API所提供的功能还不够,就可以通过Kotlin的扩展方法和扩展属性完善它。&/p&&br&&br&&h2&&strong&中场&/strong&&/h2&&p&以上说的种种风格与语法都有助于以声明的方式动态构建View层级,使Kotlin成为一个“域确切”(domain specific)的语言。比如,综合使用上述所有功能,我们可以写一个设置了左内边距属性的两个TextView:&figure&&img src=&https://pic3.zhimg.com/v2-7b16d406ffbff_b.jpg& data-rawwidth=&585& data-rawheight=&346& class=&origin_image zh-lightbox-thumb& width=&585& data-original=&https://pic3.zhimg.com/v2-7b16d406ffbff_r.jpg&&&/figure&&/p&&p&就这一段代码而言还是不错的,而且肯定比传统方式强一些。不过,语法还能更加紧凑,还有提升的空间。&/p&&p&&strong&如何给特定的layout参数属性赋值?&/strong&&/p&&p&从上面的代码中我们不容易发现,想给一个LinearLayout设置某个特定的layout参数是很难的。到现在为止,我们都在通过把给定LinearLayout.LayoutParams对象赋值给View对象的layoutParams虚拟属性来给View设置宽高。但当我们需要设置gravity属性呢?可能你想这么写:&figure&&img src=&https://pic4.zhimg.com/v2-e01b8392cfb591f95e10dc4282fa71fa_b.jpg& data-rawwidth=&640& data-rawheight=&63& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic4.zhimg.com/v2-e01b8392cfb591f95e10dc4282fa71fa_r.jpg&&&/figure&&/p&&p&编译器不同意的原因是,View的所有layoutParams属性都是ViewGroup.LayoutParams类型,也就是所有其他LayoutParams的超类,为了设置LinearLayout的属性,就需要向下转型。&/p&&p&在Java中我们需要将LayoutParams转型或是重新赋值,但在Kotlin我们可以利用一个名叫with的标准库函数来处理LayoutParams。with方法接收一个对象和一个用于处理该对象的lambda with receiver。描述起来可能没什么厉害的,但它的语法是这样的:&figure&&img src=&https://pic3.zhimg.com/v2-27c4d86a9473a2dcb709a7fd06a43521_b.jpg& data-rawwidth=&501& data-rawheight=&202& class=&origin_image zh-lightbox-thumb& width=&501& data-original=&https://pic3.zhimg.com/v2-27c4d86a9473a2dcb709a7fd06a43521_r.jpg&&&/figure&&/p&&p&请注意这里我们可以同时将layoutParams转型为LinearLayout.LayoutParams并将其作为receiver通过lambda快速访问其属性。&/p&&p&还有一点需要知道的就是Android View容器会在子View生成时自动生成一个layout参数对象并赋值给子View。在这里,当把一个TextView添加进LinearLayout时,会自动生成一个LinearLayout.LayoutParams并赋值给TextView的layoutParams属性。也就是说,我们并不需要自己创建一个LayoutParams对象,直接用父LinearLayout提供的就可以。记住这种情况只在将一个子View添加进一个父ViewGroup时才会发生,所以最外层的ViewGroup并不会获得这类对象,因为其没有父ViewGroup。&/p&&p&对于layout参数来讲,这种语法可能还有改善的控件,但已经很直白了。&/p&&p&&strong&现在,我要让“v”方法消失&/strong&&/p&&p&伴随我们这么久的v方法已经很方便了,但其语法还有简化的控件。如果能像下面这样构建一个View层级岂不是更好?&/p&&div class=&highlight&&&pre&&code class=&language-kotlin&&&span&&/span&&span class=&n&&linearLayout&/span& &span class=&p&&{&/span&
&span class=&n&&textView&/span& &span class=&p&&{&/span&
&span class=&c1&&// 各属性...&/span&
&span class=&p&&}&/span&
&span class=&n&&textView&/span& &span class=&p&&{&/span&
&span class=&c1&&// 各属性...&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&这样写显得更加自然,且可读性有很大的提升。(长得挺像Gradle)实现这种语法的技巧就是给每一种View类型定义一个缩写形式。所以为了实现上述代码,我们需要一个叫linearLayout的方法和v等价,还需要一个textView方法和v等价。在Kotlin中这不难实现:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-ef30daa90c0_b.jpg& data-rawwidth=&640& data-rawheight=&129& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic1.zhimg.com/v2-ef30daa90c0_r.jpg&&&/figure&&p&在这里我为每一种View类型写了两个方法来适配各种被调用的情况,因为在前面v方法可以被Context或ViewGroup调用。Kotlin中支持这种声明的语言特点叫做单一表述方法single expression function。这是一种针对方法的特殊语法,可以让你:&/p&&ol&&li&&p&省略方法体的大括号。&/p&&/li&&li&&p&通过表述的返回类型猜测方法的返回类型。&/p&&/li&&li&&p&省略return关键字。&/p&&/li&&/ol&&p&现在我们通过这些方法来重新构建上面的View层级:&/p&&p&&figure&&img src=&https://pic4.zhimg.com/v2-900de475fbaa76b52d27be_b.jpg& data-rawwidth=&579& data-rawheight=&353& class=&origin_image zh-lightbox-thumb& width=&579& data-original=&https://pic4.zhimg.com/v2-900de475fbaa76b52d27be_r.jpg&&&/figure&所以只要你愿意给每一种要用到的View类型定义一个缩写函数,这还是挺有用的。&br&&/p&&br&&br&&h2&&strong&Kotlin实用吗?&/strong&&/h2&&p&到现在为止,我们通过type-safe builder模式、扩展方法与扩展属性、lambda with receiver写了一个快速构建View层级的方法。&/p&&p&所以你现在可能要问:我到底要不要以这种方式在我自己的APP中构建View?到现在为止,我一直在说这样做可以很简单很方便,但只与在Java中进行同样工作进行了比较,结果不言自明。不过在Android中我们一般通过XML资源来描述View,所以我们来对比一下通过XML与通过Kotlin的type-safe builder来构建View哪种更强一些。&/p&&p&&strong&当Activity配置改变&/strong&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-5c3dee83ad1efa6e3aa4d8d725e8463a_b.jpg& data-rawwidth=&640& data-rawheight=&405& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic4.zhimg.com/v2-5c3dee83ad1efa6e3aa4d8d725e8463a_r.jpg&&&/figure&&p&Android设备中配置随时会改变,最简单的一种改变就是屏幕方向。当然还有其他各种改变,具体参见官方文档。方向的改变对Android View的影响极大,因为我们经常会针对竖向和横向写两套布局。&/p&&p&对于XML布局而言,无需自己更新UI来应对配置改变,只需要写两套布局,一套放在res/layout-land下,另一套放在res/layout-port下就好。当在这两个目录中给文件相同的命名时,Android就会针对各种情况自己找到正确的文件来填充。总而言之,无需自己写代码来处理方向改变。&/p&&p&但当处理动态生成的layout时,就需要自己处理配置信息的改变了。如果你想要对各种配置有不同的布局,就需要自己写逻辑来判断要生成何种View。如果你总是需要这么做,代码就会变得笨重。&/p&&p&所以,如果对于每种配置信息要填充不同的UI,XML布局更加方便。&/p&&p&&b&当需要处理RelativeLayout等复杂布局&/b&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-eef35a638bb6fc9f_b.jpg& data-rawwidth=&640& data-rawheight=&339& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic2.zhimg.com/v2-eef35a638bb6fc9f_r.jpg&&&/figure&&p&RelativeLayout让我们以一种非常灵活的方式进行相对布局。你可以很简单地声明一个View要放在另一个锚View的上面下面左边右边,做这件事时需要将锚View的ID传入前者。View ID还用于在代码中对特定View进行配置修改。&/p&&p&在Android中,最好的方式就是让编译器自己给View ID赋值,你不应自己写ID,也就是说,你需要使用Android工具来指定这些ID以备后面使用。&/p&&p&在XML布局中,创建一个View ID很简单,只需要这样:&/p&&div class=&highlight&&&pre&&code class=&language-kotlin&&&span&&/span&&span class=&p&&&&/span&&span class=&n&&TextView&/span& &span class=&n&&android&/span&&span class=&p&&:&/span&&span class=&n&&id&/span&&span class=&p&&=&/span&&span class=&s&&&@+id/tv&&/span& &span class=&p&&...&/span& &span class=&p&&/&&/span&
&/code&&/pre&&/div&&p&@+id注解会告诉Android定义一个叫做tv的新ID,或是重用有同样名称的已存在ID。代码不能更简单。&/p&&p&当处理动态生成的布局时,无法通过代码动态创建ID,为了创建新ID,你需要在XML中定义一个新ID,然后再在代码中通过编译后的R类来获取ID的引用。所以,动态操作View就要牵扯到另一个文件,而且在Android中,即使一个ID不再被引用,也不会被删除。&/p&&p&总的来说,在XML不居中更容易操作View的ID,因为有工具来支持ID的动态管理。&/p&&p&&b&如果需要在给View属性赋值时进行计算&/b&&/p&&p&计算View的属性很常见,比如设置其内部文本时,或是背景色、尺寸时。&/p&&p&Android XML布局语言完全是声明性的,你不能在赋值字符串中进行计算。也就是说这些属性必须在View被填充后动态修改。这样一来布局文件中的定义与代码中的修改会被分开。Android开发者对这一点可并不陌生。&/p&&p&但当你动态构建View时,你可以直接将计算结果赋值给View属性,也可以将某个属性设置的与另外一个属性一样,毕竟我们经常需要给marginLeft和marginRight设置同样的值。&/p&&p&既然当动态构建View时可以享受代码带来的所有灵活性,在赋值方面肯定是动态创建View更加方便,尤其是配合Kotlin的type-safe builder。&/p&&p&&b&如何进行布局微调&/b&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-dff3be59e8a56abdf30818_b.jpg& data-rawwidth=&640& data-rawheight=&308& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic2.zhimg.com/v2-dff3be59e8a56abdf30818_r.jpg&&&/figure&&p&除非你能看到代码就能想象出图形界面,你肯定需要使用Android Studio的布局预览来对XML布局进行微调,而不需要构建项目并在终端上跑起来。&/p&&p&当你动态编写布局时,你不能快速预览。不过随着Android Studio2.0中Instant Run功能的推出,这一点不再那么困扰人了。但是就现在而言,修改布局的最简单的方式还是Android Studio预览功能。&/p&&p&&strong&两种方式的性能如何?&/strong&&/p&&p&性能是考量填充View与动态构造View优劣的重要指标。在我一开始测试的时候,我发现构建一个简单的布局比填充几乎快一倍!但当我开始使用更多的Kotlin语法特色,并构建更复杂的View时,差别就不那么大了。在我的Nexus 6P上,我发现动态构建所花的时间约是填充的四分之三。我猜测这是因为填充时需要先解析布局资源然后构建View。&/p&&p&顺带说一句,在两种情况中,构建一个有5个View的View层级所花的时间均小于1秒,所以除非你要构建很多View,性能上不需要担心太多。&/p&&p&如果你想自己测试一下,源码可以在我的Github上找到(&a href=&https://link.zhihu.com/?target=https%3A//github.com/CodingDoug/kotlin-view-builder& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CodingDoug/kotlin-view-builder&/a&)。&/p&&p&&b&使用Kotlin的大小上限是多少?&/b&&/p&&p&在第一部分中我们提及了有关在Android中使用Kotlin的大小需求问题。你需要声明一个运行时和一个标准库的依赖。每当你想给一个Android app添加一个依赖,都应该考虑一下大小,尤其当你不能使用multidex时。&/p&&p&在Kotlin1.0.0中,运行时+标准库的大小总共是210k+636k=846k,这对一个库来说真的不小了。使用dex-method-counts统计出的方法数为6584,这只包含kotlin包下的,没有算里面引用的Java runtime方法。这一下就占了一个dex的10%的方法数。但当在我的测试工程上使用了ProGuard后,数目一下减到42个方法。最终的数目自然会增加,因为还需要用到Kotlin中的其他方法。在包含Kotlin的应用中使用ProGuard可以有效控制其大小。&/p&&br&&br&&h2&&strong&总结&/strong&&/h2&&p&Kotlin用起来还是很愉快的,它可以直接应用在Android开发中。对于构建View来讲,它不是特别的厉害,因为使用XML布局有诸多优势,就现在而言是最佳的方式。但在某些情况下动态的构建View更符合需求,此时Kotlin就能很大程度上简化代码、优化风格。&/p&&p&你可能在思考使用Kotlin有没有其他的坑。这个问题问得好,在Reddit上有讨论(&a href=&https://link.zhihu.com/?target=https%3A//www.reddit.com/r/androiddev/comments/47613n& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Can we talk about the downsides of using Kotlin? o r/androiddev&/a&)。&/p&&p&如果你想看一看我的测试项目,并将XML布局与Kotlin进行比较,可以clone我的这个repo(&a href=&https://link.zhihu.com/?target=https%3A//github.com/CodingDoug/kotlin-view-builder& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&github.com/CodingDoug/k&/span&&span class=&invisible&&otlin-view-builder&/span&&span class=&ellipsis&&&/span&&/a&)&/p&&p&希望你一路读下来能有所收获!&/p&&br&&br&&blockquote&原文链接:&a href=&https://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s%3F__biz%3DMzA3ODg4MDk0Ng%3D%3D%26mid%3D%26idx%3D1%26sn%3De7e3cffeebd4f648b4c15%26scene%3D27%23wechat_redirect& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&实战kotlin@android(三):扩展变量与其它技巧&/a&&/blockquote&
这是Kotlin开发系列文章的第三篇,也是最后一篇。在前面的两篇文章中,我们探索了如何使用Kotlin来进行部分实用Android开发工作。如果你没有看过,建议可以先看一下:
&figure&&img src=&https://pic1.zhimg.com/v2-0e8d910bb1d89aac4ba69d_b.jpg& data-rawwidth=&1300& data-rawheight=&600& class=&origin_image zh-lightbox-thumb& width=&1300& data-original=&https://pic1.zhimg.com/v2-0e8d910bb1d89aac4ba69d_r.jpg&&&/figure&&b&前言&/b&:几天前,在Google I/O大会上,Kotlin被官方宣布为新的Android一级开发语言,这条消息随后在圈内炸开了锅。相比于其他行业,程序员估计是最有效率的一波人了,这不,才几日新框架SwiftKotlin就应运而生...&p&小编在这大浪的推动下关注了一波,随即发现去年这个时候发布在各大平台的几篇关于Kotlin@Android的文章,虽然小编看不太明白,不过确实有种不明觉厉的气息透过屏幕震慑到小编眼睛,这种感觉就像是有人隔着电脑屏幕对你的眼睛轻轻吹气...&/p&&br&&blockquote&&strong&版权声明&/strong&&br&本文作者:Doug Stevenson&br&译者:程大治&br&本文由作者授权翻译并发布,首发于移动开发前线公众号,未经译者授权禁止转载。&/blockquote&&br&&p&在过去的一年中,在Android开发圈有一个越来越火的话题,就是JetBrains开发的新JVM语言Kotlin。这个团队还开发了IntelliJ Idea,也就是Android Studio的基础。Kotlin旨在通过全新的语言特色来替代老旧而不cool的Java,又由于Kotlin可以100%兼容Java,所以你在项目中可以想用多少用多少。而又因为Kotlin的标准库很小,很适合在资源有限的移动设备上开发使用&/p&&p&Kotlin能干所有Java能干的(不止),且语法更准确,代码更好看,而且在IntelliJ和Android Studio中有很好的支持。我从2009年开始从事深层次Android开发工作,我尤其关心Kotlin可以给Android开发者带来什么。所以我就不说虚的了,直接开始写Kotlin代码,让大家感受其语言特点,希望最终能带给大家有用的信息。&/p&&p&在第一部分中,我会通过最简单的方式在一个新Android项目中集成Kotlin。&/p&&br&&h2&&strong&在Android项目中配置Kotlin&/strong&&/h2&&p&官方文档讲了如何一步步安装Kotlin插件,并使用插件在Android项目中自动修改Gradle文件来添加对Kotlin的支持。我不建议大家这么做,因为这样自动完成的结果可能并不完美,即使修改后的Gradle文件工作正常,也会打乱Android项目中Gradle文件的一般形式。&/p&&p&说实话,我一直不喜欢有些Android Studio插件直接修改Android build文件,因为经常搞得很乱,我又得一点一点清理直到符合我的风格。Gradle构建文件也是源代码,而这些插件并不擅长修改已经存在的代码。所以如果你也和我一样有些挑剔,那就多花一分钟和我一起手动配置。&/p&&p&下面我们要分四步完成Kotlin的配置。&/p&&ol&&li&&p&新建一个Android项目。&/p&&/li&&li&&p&修改Gradle代码来添加Kotlin Gradle插件与标准库。&/p&&/li&&li&&p&在IntelliJ或Android Studio中添加Kotlin插件。&/p&&/li&&li&&p&将Java类文件转换成Kotlin。&/p&&/li&&/ol&&br&&p&首先,直接以默认方式新建一个Android项目,此时应该自带一个Activity。之后,要在两个build.gradle文件中添加五行重要代码,我都在其后添加了注释。下面让我们先修改最高层的build.gradle脚本,添加两行代码。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-169ab78e150ddd51a8389d02_b.jpg& data-rawwidth=&640& data-rawheight=&190& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic3.zhimg.com/v2-169ab78e150ddd51a8389d02_r.jpg&&&/figure&&p&这样就会在项目构建时添加Kotlin Gradle插件。请注意上面在ext.kotlin_version中标注的kotlin版本字符串,我们一会还要在app模块的compile dependencies中用到它,而且两个地方版本必须相符。你最好使用官方文档中最新版本。&/p&&p&然后,在app模块自己的build.gradle文件中紧随Android plugin添加kotlin-android plugin。这样整个项目就整合了Kotlin,在build项目时会编译Kotlin文件,这样最后所有的类文件都会打包在一个app中。&/p&&p&&figure&&img src=&https://pic4.zhimg.com/v2-5cdc5db43_b.jpg& data-rawwidth=&456& data-rawheight=&72& class=&origin_image zh-lightbox-thumb& width=&456& data-original=&https://pic4.zhimg.com/v2-5cdc5db43_r.jpg&&&/figure&惯例上,Kotlin文件存放在src/main/kotlin路径中,但也可以把他们和Java文件一起放在/src/main/java路径中。这里我们还是按照惯例,并在Gradle中标注一个新的Kotlin源路径。&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-59a485df622b01afa3291_b.jpg& data-rawwidth=&623& data-rawheight=&140& class=&origin_image zh-lightbox-thumb& width=&623& data-original=&https://pic1.zhimg.com/v2-59a485df622b01afa3291_r.jpg&&&/figure&&p&不要忘了新建这个路径,一会就要用到了。最后需要添加一个Kotlin依赖,直接使用build.gradle中的kotlin版本变量。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-84bd8ed2ade10d_b.jpg& data-rawwidth=&634& data-rawheight=&123& class=&origin_image zh-lightbox-thumb& width=&634& data-original=&https://pic4.zhimg.com/v2-84bd8ed2ade10d_r.jpg&&&/figure&&p&不过这个包有多大呢?好问题!每当我们添加新的依赖时,都应该搞清楚这个包有多大。不过对于这个问题,我会在后面的文章中回答。&/p&&p&这就是Kotlin Gradle插件,走完这些步骤后,就可以在项目中运行Kotlin代码了。不过你还需要添加IDE对Kotlin的支持,所以如果你还没有安装IntelliJ或Android Studio的Kotlin插件,那就赶快安装。安装Kotlin插件就像安装其他任何插件一样,可以在Preferences-&Plugins-&Insall JetBrains plugin下找到。安装后要重启IDE,做完这一步后,准备工作就完成了。我发现IDE对Kotlin的支持甚至和Java语言一样好。这也可以理解,毕竟IDE和Kotlin都是JetBrains开发的嘛。&/p&&br&&h2&&b&快速将Java转成Kotlin&/b&&/h2&&p&IDE插件有一个很有趣的功能就是将Java文件直接转成Kotlin。这个插件可以很智能地将Java语言风格转换成Kotin风格并保持运行兼容。如果你创建了一个Android项目,那就找到自动生成的MainActivity,在左边的项目结构中选中,并触发IDE的action &Convert Java File to Kotlin File&。你可以按下快捷键Command+Shift+A(OSX)来选择action。这个插件甚至有专门针对这个action的快捷键Option+Shift+Command+K(OSX)。其实官方并不建议直接转换Java文件,但直到现在我还没遇到过什么问题。&/p&&p&如果你按我说的操作转换了Java文件,就会在原本.java文件的地方找到一个.kt文件。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-ab9cc348bf7e4cc438d7c5b_b.jpg& data-rawwidth=&640& data-rawheight=&282& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic1.zhimg.com/v2-ab9cc348bf7e4cc438d7c5b_r.jpg&&&/figure&&p&你可以看到现在MainActivity在右下角有一个K标志(这里隐藏了.kt扩展名)。由于我们刚刚专门为Kotlin配置了一个路径,我们把Kotlin文件拖进kotlin文件夹中。注意要保留kotlin文件中类的包名,不然项目无法运行。&/p&&p&如果你想在项目中只用Kotlin,那可以干脆删除掉Java文件夹,把所有的Kotlin文件放在kotlin路径中。之后,项目结构就像下面这样。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-efbdf_b.jpg& data-rawwidth=&640& data-rawheight=&244& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic4.zhimg.com/v2-efbdf_r.jpg&&&/figure&&p&从新的Activity中你可以大概知道Kotlin长什么样。我下面说几点Kotlin与Java很不一样的地方:&/p&&ul&&li&&p&在Kotlin中你见不到&new&关键字。&/p&&/li&&li&&p&把类名当做方法并传入参数就可以直接构造对象。&/p&&/li&&li&&p&数据类型关键字被val(final)与var(variable)取代,Kotlin可以自己判断数据是什么类型。&/p&&/li&&/ul&&br&&h2&&b&中场休息&/b&&/h2&&p&刚才我们一步一步在Android项目中添加了Kotlin支持,现在我们要开始通过代码直观感受Kotlin的语言特色以及它能如何简化Android开发。&/p&&p&当我第一次接触Kotlin并了解其语言特色功能时,有一点让我感触很深,那就是type-safe builders。它让你以陈述式语言风格来创建对象,其语法很类似Gradle,但Gradle和Groovy代码是动态编写的,而kotlin是静态编写的,所以编译器可以在属性的值不合法时告诉你。&/p&&p&type-safe builders的一个典型用法就是构建嵌套式数据结构,比如XML。在Android中有很多XML文件,如layouts和views。如果Kotlin可以以程序的方式动态编写XML,它可能很善于处理层级问题。所以我决定尝试使用Kotlin创建一个动态构建View层级的工具。如果是在Java中做这件事,代码量之大可以想象。&/p&&p&注意:在后面的代码中我会经常使用lambda,所以在继续阅读之前,确保你了解lambda的基本形式。简而言之,lambda是要作为参数被传入某方法或赋值给某变量的匿名方法的简化表现形式。&/p&&p&type-safe builders可行还要归功于Kotlin的一个特色功能:lambda with receiver。下面我们要看一个能真正有用的案例。kotlin可以在类的外面定义方法,我在这里就是这么干的。还要注意变量的名字是在类型之前的,这一点与Java语言正相反。&/p&&p&&figure&&img src=&https://pic4.zhimg.com/v2-156eddea17a1ed5d03eb20c_b.jpg& data-rawwidth=&640& data-rawheight=&193& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic4.zhimg.com/v2-156eddea17a1ed5d03eb20c_r.jpg&&&/figure&简便起见,我将上面的方法命名为v,在之后的系列文章中我还会使用到这个方法。这个方法是这么调用的:&br&&/p&&p&&figure&&img src=&https://pic4.zhimg.com/v2-9de58ae40dd4b4c07f37cc90d542440e_b.jpg& data-rawwidth=&581& data-rawheight=&216& class=&origin_image zh-lightbox-thumb& width=&581& data-original=&https://pic4.zhimg.com/v2-9de58ae40dd4b4c07f37cc90d542440e_r.jpg&&&/figure&这段代码和填充下面这段XML是等效的。&br&&/p&&p&&figure&&img src=&https://pic3.zhimg.com/v2-a340b1b075c8cadc163ff_b.jpg& data-rawwidth=&451& data-rawheight=&121& class=&origin_image zh-lightbox-thumb& width=&451& data-original=&https://pic3.zhimg.com/v2-a340b1b075c8cadc163ff_r.jpg&&&/figure&OK,如果这是你第一次看Kotlin代码,相信有不少需要翻译的。下面解释一下刚才代码中涉及的几个语法。&br&&/p&&p&&b&&reified TV : View&&/b&&/p&&p&reify的意思是具体化。而作为Kotlin的一个方法泛型关键字,它代表你可以在方法体内访问泛型指定的JVM类对象。这段代码的意思就是v方法要使用命名为TV(意为Type of View,即View种类)的reified泛型,它指定类必须为View或其子类。必须以内联方式声明这个方法才有效。调用者要给TV指定一个具体的类型。&/p&&p&&b&init: TV.() -& Unit&/b&&/p&&p&v方法有两个参数,一个是Context,一个是lambda风格的init。init在这里很特殊,因为它是一种lambda with receiver类型的方法引用。lambda with receiver是一个要求特定类型的对象的代码块,这里要求的对象在lambda代码中通过this关键字引用。在这里receiver对象就是reified泛型TV。&/p&&p&在我们这个例子中,v要创建一个类型为TV的对象,需要调用者告诉它如何创建。这个新创建的TV类型对象会成为给定的lambda的receiver,labmda通过view.init()在v中被调用,以便对view进行操作。“-& Unit”意思是lambda返回Unit类型,就如Java中的Void一样,即什么也不返回。&/p&&p&总结一下这里的lambda with receiver:&/p&&ul&&li&&p&v声明了一个名叫init的参数,它是TV类型的lambda with receiver。&/p&&/li&&li&&p&v创建并初始化一个TV对象,并在其上调用lambda来初始化它。&/p&&/li&&li&&p&lambda在自己代码块中通过this关键字引用TV对象。&/p&&/li&&/ul&&br&&p&&b&TV::class.java&/b&&/p&&p&通过TV::class.java表达你可以引用reified泛型TV的Class对象。这种表达在Kotlin中专门针对reified泛型,与Java相比,可以大量减少代码。&/p&&br&&p&到这里,估计你会有一些问题:&/p&&p&&b&为什么v有两个参数,而调用的时候似乎只给了一个?&/b&&/p&&p&这个只是因为Java程序员对Kotlin语法并不熟悉。在Java中,一个方法的所有的参数都要写在圆括号内,所以当有匿名回调方法时会变得很长。但在Kotlin中,当lambda时最后一个参数时,有一个特殊语法,即lambda出现在紧随圆括号的大括号中。你可以把所有的代码都放在圆括号内,但大多数情况下这么写代码会显得更加简洁,而且可以使一组圆括号保持在一行里,更易于追踪。另外,这种语法在传入只有一个方法的匿名内部类比如Runnable时也可以派上用场。&br&&/p&&br&&p&&b&layoutParams和text是变量吗?&/b&&/p&&p&lambda with receiver的一个语法特色就是当操作this的方法或属性时this关键字可以省略。但在上面的调用例子中layoutParams和text到底是什么?其实这些属性是Kotlin提供的receiver类型(TV)的属性。因为TextView有setLayoutParams()与setText()等方法,Kotlin会自动识别这些JavaBean风格的方法并为他们创建属性,好像它们是类的成员变量一样。所以这里text = &Hello&等价于this.setText(&Hello&)。下面是在安装了Kotlin插件的Android Studio中的截图,里面展示了自动完成的内容。&/p&&p&&figure&&img src=&https://pic3.zhimg.com/v2-883ac55eb30df0dca6921f_b.jpg& data-rawwidth=&640& data-rawheight=&360& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic3.zhimg.com/v2-883ac55eb30df0dca6921f_r.jpg&&&/figure&如你所见,Kotlin插件之处text属性是从TextView(receiver对象)中JavaBean风格的getter/setter方法中派生出的。&br&&/p&&br&&p&&b&构造器到底是怎么运作的?就不能new TV(context)吗?&/b&&/p&&p&因为编译器也不知道在v方法内部TV到底是什么类型,我们不能new它的对象。不过我们可以利用reified Class对象(TV::class.java)来获取仅有一个context参数的构造器。View都有这样一个构造器,不然我们也写不出这个程序。我们通过构造器对象来获得TV类型的实例,就如Java中的new关键字一样。想一想我们可以通过一个方法适配所有View,而不再针对每个View单独写方法,这一点小麻烦还是很值的。在后续系列文章中我们也会优化这个方法。&/p&&p&这几行代码真的很大的简化了我们的工作。如果你刚刚接触Kotlin,建议你从头再消化一遍,毕竟许多概念和Java差别很大。我自己也花了好多时间来理解这些概念。&br&&/p&&p&这些都只是开始,这个方法有很多地方可以完善和升级,使之更加易用。比如我想用用一行代码构造一整个View层级。所以不要走开,我会在后续文章探索Kotlin还能做什么。&/p&&br&&blockquote&原文链接:&a href=&https://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s%3F__biz%3DMzA3ODg4MDk0Ng%3D%3D%26mid%3Didx%3D1%26sn%3Dffaa512eafeed%26scene%3D27%23wechat_redirect& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&实战Kotlin@Android(一):项目配置和语言转换&/a&&/blockquote&
前言:几天前,在Google I/O大会上,Kotlin被官方宣布为新的Android一级开发语言,这条消息随后在圈内炸开了锅。相比于其他行业,程序员估计是最有效率的一波人了,这不,才几日新框架SwiftKotlin就应运而生...小编在这大浪的推动下关注了一波,随即发现去…
不错。&br&&br&银行、证券等等金融行业&br&阿里、京东等电商行业&br&移动、电信等通信行业&br&电、水、能源等公共服务行业&br&政府的电子政务&br&大中型企业管理系统&br&.....&br&基本上都用Java开发的系统 ,&br&以前有小部分.net开发的,现在越来越少。&br&&br&所谓的互联网,前端(PC端、移动端)可能各不一样,后台只要用户上规模了还是Java为主。&br&&br&至于个人的发展前景,完全依赖于个人的努力以及机遇了。&br&所以开始从事这个行业的时候,不要完全从薪资出发(不是不考虑,但现在太多的人太考虑金钱了)。&br&能不能学到技术是主要要考虑的方面,&br&公司所在的行业前景、公司发展前景也是要考虑的。&br&&br&骑上一匹好马(公司),在大道(行业)前进,不要总是换马换道路,除非以前的选择是有问题的,剩下的就是好好学习、好好发挥。&br&年年换公司会让你的工资像加了发酵一样发起来,但是你的底蕴就没了,一个公司会重用坚持的人,不会重用一个年年换公司的人,一个拼现在一个拼未来。&br&&br&&b&2017年宏观经济会相对比较差,可能比2016年更差,绝大多数行业会受到影响,所以IT方面,硬件行业、软件行业、互联网行业,肯定会受到波及,一般来说,会比其他实体经济好点,但这个谁也无法预料,所有在业内的或者想进入行业内的,都应当注意了。&/b&&br&&br&&br&可以了解以下问题的我的答案:&br&&a href=&https://www.zhihu.com/question//answer/& class=&internal&&自学编程的人,都是怎么找到第一份软件开发工作的? &/a&&br&&br&------------------------------------------------------
不错。 银行、证券等等金融行业 阿里、京东等电商行业 移动、电信等通信行业 电、水、能源等公共服务行业 政府的电子政务 大中型企业管理系统 ..... 基本上都用Java开发的系统 , 以前有小部分.net开发的,现在越来越少。 所谓的互联网,前端(PC端、移动端…
作为面试过android开发的面试官,我来从我的角度出发,来解答一下楼主的困惑。&br&&br&1) Java基本功,这个是必备知识。如果说面试到时很少用,并不代表后面项目不会用到。而且,如果基本知识都掌握不好,说明还有很多提高的空间。&br&&br&2) Android基本知识也是要的。如果连android基本知识都理解不深刻,那我估计想开发出一款好的软件也没那么容易。&br&&br&3) 面试的问题不常用或是比较难的,其实,说明面试官想对你做深层次地考核,答得上来是加分项。&br&&br&4) 面试官也很忙的,面试题大多也是网上找到。&br&&br&5) 有时候,需要的并不是标准的答案,而是看你的学习能力、知识广度、分析问题的思路、解决问题的技巧等等,这个才是面试官关心的。&br&&br&同时,这里也补充一些面试技巧&br&1) 碰到不会的问题不要慌,我们要的不是完美的开发者,积极承认自己的不足,甚至可以带着求知的欲望,反过来请教面试官,让他看到你好学的一面。即使面试失败,也算学到新知识,去下一个面试的时候,可以避免踩同样的坑。&br&2)突出团队协作能力和自己的沟通能力,能和面试官谈笑风生,这样才能博得好感。&br&3)突出你的特点或优势,有时候面试的问题并不能很好地展现你的能力时,这时候就要主动表达出来,自己在哪些方面的装长。记得有一次,我面试完一个人,我再问他自己有哪些优势时,他和我说,虽然是app开发,但懂framework层的工作原理,自己有3年framework层的开发经验。后面我们又继续聊了一下,发现掌握的知识还是蛮多的,后面更加坚定地要了这个人。&br&&br&附上一片文章,可以学习一下&br&&a href=&//link.zhihu.com/?target=http%3A//mp.weixin.qq.com/s%3F__biz%3DMzI3NDA3Njg3Mw%3D%3D%26mid%3D%26idx%3D1%26sn%3Deeea22203ab90cbb9f5a22b117fe9503%26scene%3D0%23wechat_redirect& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&mp.weixin.qq.com/s?&/span&&span class=&invisible&&__biz=MzI3NDA3Njg3Mw==&mid=&idx=1&sn=eeea22203ab90cbb9f5a22b117fe9503&scene=0#wechat_redirect&/span&&span class=&ellipsis&&&/span&&/a&
作为面试过android开发的面试官,我来从我的角度出发,来解答一下楼主的困惑。 1) Java基本功,这个是必备知识。如果说面试到时很少用,并不代表后面项目不会用到。而且,如果基本知识都掌握不好,说明还有很多提高的空间。 2) Android基本知识也是要的。如…
&figure&&img src=&https://pic4.zhimg.com/v2-eb08fd47e_b.jpg& data-rawwidth=&900& data-rawheight=&500& class=&origin_image zh-lightbox-thumb& width=&900& data-original=&https://pic4.zhimg.com/v2-eb08fd47e_r.jpg&&&/figure&&p&了解我的人知道,我是一名不折不扣的 G 粉,一直在关注 Google,最近 Google 有一些小动作,可能很多人不太了解,借这个机会,给大家普及下。&br&&/p&&br&&p&而且断断续续有人问我一些这样的问题,比如:&/p&&br&&blockquote&&p&Android 的前景怎么样?&/p&&p&我想学习编程,到底学什么更好呢?&/p&&p&移动互联网已经走下坡路了,下一个风口是什么呢?&/p&&/blockquote&&br&&p&对于 Google 的一些动作,我有一些思考以及自己的看法,分享给你们,很可能看完之后以上问题就有答案了。&/p&&br&&br&&h2&PWA&/h2&&br&&p&可能很多人没听过 PWA,PWA 是 Progressive Web Apps 的简称,意为渐进式 Web App 的意思,是 Google 在 2015 年推出的一个项目,致力于将网页 app 化,我们知道 Web 与原生应用各有优劣,而 Google 一直致力于 Web 与原生应用体验的最好结合,而 PWA 就被寄予厚望。&/p&&br&&p&简单来说,你可以把 PWA 理解成是类似微信小程序,所以业内也把 PWA 成为 Google 小程序,只不过 PWA 是系统级的,而微信小程序是基于微信生态的,而就在前几天,Google 官方博客宣布,PWA 会深入集成到 Android 系统中,并且将获得与安卓原生应用同等的待遇与权限,在即将到来的 Chrome 测试版中,PWA 不仅在主页有快捷入口,而且还会出现在应用列表以及系统设置中,甚至还可以收到推送,这意味着 PWA 将获得更接近于原生应用的使用体验,以下是官方的演示图片:&/p&&br&&figure&&img src=&https://pic4.zhimg.com/v2-f5bd7a0e3eee595bd192aec3_b.jpg& data-rawwidth=&720& data-rawheight=&405& class=&origin_image zh-lightbox-thumb& width=&720& data-original=&https://pic4.zhimg.com/v2-f5bd7a0e3eee595bd192aec3_r.jpg&&&/figure&(渣乎不支持 gif,可以到这里 &a href=&http://link.zhihu.com/?target=http%3A//stormzhang.com//google-events/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&stormzhang.com/2017/02/&/span&&span class=&invisible&&16/google-events/&/span&&span class=&ellipsis&&&/span&&/a& 查看原图。) &br&&p&相比较于刚推出没多久,只有三分热度的微信小程序,我更看好 PWA,相比较依赖于微信的微信小程序,跟 Android 系统深度融合的 Google 小程序更有想象力,毕竟微信 App 本身也得依赖于 Android 系统。&/p&&br&&br&&h2&Android Instant Apps&/h2&&br&&p&说到 PWA,就不得不提到 Google 的另一个项目 Android Instant Apps。Instant Apps 是 16 年的 IO 大会上被提出来, 它的概念是这样的:你使用的是 Android 手机,朋友给你发了一个链接,这个链接是一个支持 Instant Apps 特性的应用,你点击该链接,将直接进入该应用,无须安装,之后就可以进行任何关于该应用的操作。&/p&&br&&p&它的加载速度很快,它的加载方式会让你以为你在打开一个移动网页,然而它确是 Android 原生应用,我们来看下官方提供的一个演示稿:&/p&&br&&figure&&img src=&https://pic1.zhimg.com/v2-18b43ded5fff52d0a9f6c6ee7133ca18_b.jpg& data-rawwidth=&300& data-rawheight=&607& class=&content_image& width=&300&&&/figure&&br&&p&看了这个图什么感觉?理解了没?&/p&&br&&p&它的使用场景是,想想你的手机,是不是装了很多很少会用到的 App,无端的占用你很多内存与存储空间,但是呢,因为偶尔会用到,所以舍不得删。但是有了 Instant Apps 就不一样了,你以后需要什么 App,朋友直接一个链接发过来,无须下载,无须安装,直接就打开使用了,而如果后面你觉得 App 的使用很频繁,你再考虑安装该 App。太酷炫了有没有?终于解放了手机存储空间,也不用忍受下载、安装的过程,甚至可以解决国内众多 App 后台的无良服务,简直不要太激动。&/p&&br&&p&可惜的是,Instant Apps 深度链接的识别需要依赖 Google Play,然而众所周知,国内访问不了 Google Play,这个就成为最大的阻碍了,前段时间网上传言 Google Play 可能会进驻中国,据说跟网易合作,由网易代理,但是官方没有任何说明,所以,我们只能 YY 这是真的,真心期待。&/p&&br&&p&目前 Instant Apps 还在内测阶段,目前只有 Android 7.x 的设备才支持该功能,开发者只需要简单在代码中添加对 Instant Apps 的支持,编译打包重新上传应用就可以了,它的入口与 Instant Apps 的启用大概是如下图这样:&/p&&br&&figure&&img src=&https://pic2.zhimg.com/v2-17fe2cfa1bf65ebd7bd5_b.jpg& data-rawwidth=&1668& data-rawheight=&726& class=&origin_image zh-lightbox-thumb& width=&1668& data-original=&https://pic2.zhimg.com/v2-17fe2cfa1bf65ebd7bd5_r.jpg&&&/figure&&br&&p&之前大家一直围绕 Web App 和 Native App 谁才会是未来的话题来争辩,Google 的 PWA 项目想让 Web App 更接近原生的体验,而 Instant Apps 项目又致力于让原生 App 拥有 Web App 的方便与即时性,似乎 Google 在移动网页与原生应用之间并没有明确的看好谁,反而是两手都在抓。&/p&&br&&br&&h2&Andromeda OS&/h2&&br&&p&之前 Google 刚传要推出一种全新的操作系统 Andromeda OS 的时候,很多人问对 Android 开发者的影响,我写了这样一篇文章「&a href=&http://link.zhihu.com/?target=http%3A//mp.weixin.qq.com/s%3F__biz%3DMzA4NTQwNDcyMA%3D%3D%26mid%3D%26idx%3D1%26sn%3Df434e136bd93fcbb16d44c04c35fad9e%26chksm%3D87d138afb0a6b1be82c0d14eb5b3a8033a0f647eabecbc%26scene%3D21%23wechat_redirect& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Andromeda OS 来了,Android 再见?&/a&」,昨天我看了一篇对 Andromeda OS 介绍的文章,原文地址在这:&/p&&br&&p&&a href=&http://link.zhihu.com/?target=https%3A//techspecs.blog/blog//googles-not-so-secret-new-os& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Google’s not-so-secret new OS&/a&&/p&&br&&p&这篇文章提到,Andromeda OS 将把 Android 和 Chrome OS 并进来,Web 应用和 Android 应用都可以在上面跑,而且文中提到,新的系统支持多种语言开发,C、C++ 用来开发底层,Go 用来开发网络,Java 用来开发 Android,Python 作为脚本,而该操作系统官方开发语言很大可能是...Dart!&/p&&br&&p&对 Dart 语言不了解的可以适当的了解下,Dart 和 Go 一样,都是 Google 自家语言,看来因为跟 Oracle 关于 Java 的版权问题,Google 觉得还是使用自家语言最安全,很可能以后也会强推自家语言。&/p&&br&&br&&h2&思考&/h2&&br&&p&不止如此,Google 之前还发布了物联网操作系统 Android Things,以及刚刚正式发布的深度学习系统 TensorFlow 1.0,一切的一切,都充满想象力,Google 是想打造一个从 Web 到原生 App,到跨平台、跨终端的操作系统,再到物联网、人工智能,这是一个超级帝国啊。&/p&&br&&p&而作为开发者的我们,对我们有什么启示呢?&/p&&br&&p&首先作为 Android 开发者根本无须担心未来,毕竟亲爹 Google 太牛逼了,未来充满无限想象力,而且 Android 很可能在新的平台发挥重大作用。&/p&&br&&p&我个人认为人人都该学点编程,看看互联网这几年对我们生活的改变,几乎每个行业都跟互联网有关,毫无疑问,未来互联网依然会改变世界。&/p&&br&&p&而对于想要学习编程的同学,我的建议是,保守点的选择 Web 前端或者 Android 开发,虽然目前市场大环境较差,但是 Web 前端跟移动端很长一段时间依然是主流。&/p&&br&&p&对于已经从事编程行业,想要学习一门新语言,拓宽下自己的知识面,不妨学习下 Python、Go 甚至提前关注下 Dart,其实语言都是通的,学会一门编程语言,再学习另一个是很快的,难的是应用场景与平台的选择。&/p&&br&&p&而如果对算法感兴趣的同学,强烈推荐选择深度学习领域,学习下 TensorFlow,尤其是还在读书,并且算法基础不错的学生朋友们,这些都是人工智能最核心的技术,但是门槛较高,不是所有人都适合学习的。种种迹象表明,继移动互联网之后,下一个风口浪尖很可能就是人工智能!&/p&&br&&br&&blockquote&本文原创发布于微信公众号 AndroidDeveloper,id:googdev,欢迎关注获取更多原创分享。&/blockquote&
了解我的人知道,我是一名不折不扣的 G 粉,一直在关注 Google,最近 Google 有一些小动作,可能很多人不太了解,借这个机会,给大家普及下。 而且断断续续有人问我一些这样的问题,比如: Android 的前景怎么样?我想学习编程,到底学什么更好呢?移动互联…
&p& 本文来自于&a href=&http://link.zhihu.com/?target=https%3A//bugly.qq.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&腾讯bugly开发者社区&/a&,未经作者同意,请勿转载,原文地址:&a href=&http://link.zhihu.com/?target=http%3A//dev.qq.com/topic/acc3c5& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&微信小程序“信用卡还款”项目实践&/a&&/p&&blockquote&&p&作者:peggy&/p&&/blockquote&&h2&小程序概述&/h2&&p& 11月3日晚,微信团队对外宣布,微信小程序开放公测。开发者可登陆微信公众平台申请,开发完成后可以提交审核,公测期间暂不能发布。&/p&&p& 我们前一段时间也进行了小程序开发,现在来对之前的开发体验做一个总结。&/p&&h4&1. 小程序是什么?&/h4&&p& 微信小程序是一种介于原生app、和web app的hybrid。通过微信进行加载,实现类似原生app的流畅。相对原生app来说,小程序更加轻量、更新实时、跨平台;相对web app来说,小程序资源离线,体验更流畅。&/p&&p& 微信小程序的设计目标是通过尽可能简单、高效的方式让开发者可以在微信中开发具有原生APP体验的服务。&/p&&p& 不说那么多了, 先来看看小程序的效果:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-f97ab7f6bb42b1d852a5e3_b.jpg& data-rawwidth=&1851& data-rawheight=&1100& class=&origin_image zh-lightbox-thumb& width=&1851& data-original=&https://pic4.zhimg.com/v2-f97ab7f6bb42b1d852a5e3_r.jpg&&&/figure&&br&&p& 看完效果,是不是对开发充满好奇~&/p&&h4&2. 小程序的实现机制&/h4&&p& 小程序的开发是基于微信提供的一套应用框架进行开发的。微信通过封装微信客户端提供的文件系统、网络通信、任务管理、数据安全等基础功能,对上层提供了一套完整的Javascript Api,使得开发者能够非常方便的使用到微信客户端提供的各种基础功能,快速构建一个应用。框架设计如下:&/p&&figure&&img src=&https://pic3.zhimg.com/v2-bc35ede1c5df932ca65c78ea_b.png& data-rawwidth=&555& data-rawheight=&525& class=&origin_image zh-lightbox-thumb& width=&555& data-original=&https://pic3.zhimg.com/v2-bc35ede1c5df932ca65c78ea_r.jpg&&&/figure&&br&&p& 框架提供了自己的视图层描述语言 WXML 和 WXSS,以及基于 JavaScript 的逻辑层框架,并在视图层与逻辑层之间通过&strong&单向数据绑定&/strong&进行数据传输,使开发者更加聚焦于数据与逻辑上。&/p&&h4&3. 支持的特性&/h4&&p& 接下来我们来看一下,微信框架具体提供的特性:&/p&&p& wxml:一切皆组件(视图组件)&/p&&ul&&li&view组件(类似 H5中的div)&/li&&li&input组件(type = digit,有带小数点的9宫格键盘)&/li&&li&modal弹窗组件 (对应的wxml、效果如下)(该组件已换js 实现wx.showModal())&/li&&/ul&&figure&&img src=&https://pic4.zhimg.com/v2-517f4ef1cceb4e6e1fa16647_b.png& data-rawwidth=&643& data-rawheight=&83& class=&origin_image zh-lightbox-thumb& width=&643& data-original=&https://pic4.zhimg.com/v2-517f4ef1cceb4e6e1fa16647_r.jpg&&&/figure&&figure&&img src=&https://pic1.zhimg.com/v2-e6bd34b2cbca493ed6ddfc_b.jpg& data-rawwidth=&529& data-rawheight=&505& class=&origin_image zh-lightbox-thumb& width=&529& data-original=&https://pic1.zhimg.com/v2-e6bd34b2cbca493ed6ddfc_r.jpg&&&/figure&&br&&p& 更多wxml组件,请查看微信公众平台小程序文档&/p&&h4&4. 功能API:&/h4&&ul&&li&支付&/li&&li&微信信息的获取&/li&&li&网络请求&/li&&li&录音&/li&&li&上传/下载文件&/li&&li&webSocket&/li&&li&访问相册&/li&&/ul&&figure&&img src=&https://pic2.zhimg.com/v2-565a7d6455fcbb28504b85_b.png& data-rawwidth=&697& data-rawheight=&348& class=&origin_image zh-lightbox-thumb& width=&697& data-original=&https://pic2.zhimg.com/v2-565a7d6455fcbb28504b85_r.jpg&&&/figure&&br&&p& 更多详细的API,请查看微信公众平台小程序文档&/p&&h4&5. 其他:&/h4&&ul&&li&下发消息通知&/li&&li&简要的统计(pv、uv)&/li&&/ul&&figure&&img src=&https://pic2.zhimg.com/v2-efd3d86eeafb0f6dce977d_b.jpg& data-rawwidth=&645& data-rawheight=&403& class=&origin_image zh-lightbox-thumb& width=&645& data-original=&https://pic2.zhimg.com/v2-efd3d86eeafb0f6dce977d_r.jpg&&&/figure&&br&&p& 现在我们来具体开发~&/p&&h2&小程序的开发流程&/h2&&h3&一、获取微信小程序的 AppID&/h3&&figure&&img src=&https://pic4.zhimg.com/v2-03e08a278b3e7a984e289ed27fe3efdf_b.png& data-rawwidth=&649& data-rawheight=&260& class=&origin_image zh-lightbox-thumb& width=&649& data-original=&https://pic4.zhimg.com/v2-03e08a278b3e7a984e289ed27fe3efdf_r.jpg&&&/figure&&br&&h3&二、创建项目&/h3&&p& 创建项目,需要通过开发者工具来完成。(工具在微信小程序公众平台下载)&/p&&figure&&img src=&https://pic3.zhimg.com/v2-6a96ecb2efc2f80a87af7bbbace87bfe_b.png& data-rawwidth=&644& data-rawheight=&282& class=&origin_image zh-lightbox-thumb& width=&644& data-original=&https://pic3}

我要回帖

更多关于 安卓开发要学什么 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信