欢迎光临
站点建设中.........

Android Studio 3.3 正式版发布

GHOST阅读(28)

Android Studio 3.3 发布了。出于用户反馈的考虑,该版本比起大的新特性更新,更关注于基础质量的提升。自上个稳定版发布以来,Android Studio 3.3 解决了 200 多个用户提交的 bug 的同时,包括了对导航编辑器(Navigation Editor)的官方支持、提升注释处理器的 Java 增量编译支持、C++ 代码的 lint 检查、升级过的项目向导和每个性能分析器的可用性修复。

Android Studio 3.3 在今年开启了称为 Project Marble 的、更广泛的质量关注领域。在这个概念里,开发团队专注于关注崩溃、挂起、内存泄露和影响用户的 bug 等数量的减少,同时花精力在测量基础测试上以防止这些问题的出现。

这是一个里程碑版本,主要有以下的更新:

开发

  • 导航编辑器(Navigation Editor) – 导航编辑器是个可视化的编辑器,可以构建支持新 Jetpack 导航组件的 XML 资源。开发者可以用导航编辑器和导航组件在应用和内容区域间,建立可预测的交互。在早些的发行版本该编辑器提供了预览,根据用户的回馈保持了这个特性。
  • IntelliJ 平台的升级、Kotlin 更新 – 新版包含了 Intellij 2018.2.2,捆绑了 Kotlin 1.3.11。
  • Clang-Tidy 对 C++ 的支持
  • 新项目向导的更新
  • 删除未使用的 IDE 目录
  • IDE 用户反馈

构建

  • 提升使用注释处理器时的 Java 增量编译
  • 延迟任务(Lazy task)的配置
  • 单变量项目的同步
  • Android App Bundles 现在支持即时应用

测试

  • 多个模拟器 AVD 实例
  • Android 9 Pie 模拟器系统镜像 & Wi-Fi P2P
  • 模拟器快照存储速度提升

优化

  • 分析器(Profiler)性能提升
  • 内存分析器分配跟踪选项
  • 网络分析器文本格式化
  • CPU 分析器帧渲染数据

更新详情 | 下载地址

常用邮箱的 IMAP/POP3/SMTP 设置

GHOST阅读(46)

POP3

POP3是Post Office Protocol 3的简称,即邮局协议的第3个版本,它规定怎样将个人计算机连接到Internet的邮件服务器和下载电子邮件的电子协议。
它是因特网电子邮件的第一个离线协议标准,POP3允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,
同时删除保存在邮件服务器上的邮件,而POP3服务器则是遵循 POP3协议的接收邮件服务器,用来接收电子邮件的。

POP3是Post Office Protocol 3的简称,即邮局协议的第3个版本,是TCP/IP协议族中的一员(默认端口是110)。

本协议主要用于支持使用客户端远程管理在服务器上的电子邮件。

POP与POP3

POP协议支持“离线”邮件存储转发处理:客户端程序连接服务器,下载所有未阅读的电子邮件;一旦将邮件从邮件服务器端送到客户端上,邮件服务器上的邮件将会被删除。

目前的POP3邮件服务器大都可以“只下载邮件,服务器端并不删除”,也就是改进的POP协议。

POP3协议允许电子邮件客户端下载服务器上的邮件,但是在客户端的操作(如移动邮件、标记已读等),不会反馈到服务器上,

比如通过客户端收取了邮箱中的3封邮件并移动到其他文件夹,邮箱服务器上的这些邮件是没有同时被移动的 。

IMAP

IMAP全称是Internet Mail Access Protocol,即交互式邮件访问协议,是一个应用层协议(端口是143)。

用来从本地邮件客户端(Outlook Express、Foxmail、Mozilla Thunderbird等)访问远程服务器上的邮件。

IMAP和POP3的区别


IMAP像POP3那样提供了方便的邮件下载服务,让用户能进行离线阅读。IMAP和POP3是邮件访问最为普遍的Internet标准协议。不同的是:

1、IMAP提供Webmail 与电子邮件客户端之间的双向通信,客户端收取的邮件仍然保留在服务器上,同时在客户端上的操作都会反馈到服务器上
(如:删除邮件,标记已读等,服务器上的邮件也会做相应的动作。所以无论从浏览器登录邮箱或者客户端软件登录邮箱,
看到的邮件以及状态都是一致的。)。而POP3在客户端的操作不会反馈到服务器上。
2、IMAP更好地支持了从多个不同设备中随时访问新邮件。
3、IMAP提供的摘要浏览功能可以让你在阅读完所有的邮件到达时间、主题、发件人、大小等信息后才作出是否下载的决定。
4、POP3需要下载未阅读的邮件,IMAP可以不用把所有的邮件全部下载,而是通过客户端直接对服务器上的邮件进行操作。
所有通过IMAP传输的数据都会被加密,从而保证通信的安全性。
5、IMAP 整体上为用户带来更为便捷和可靠的体验。POP3 更易丢失邮件或多次下载相同的邮件。

SMTP

SMTP的全称是“Simple Mail Transfer Protocol”,即简单邮件传输协议(25号端口)。
它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。
SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。

SMTP是一个“推”的协议,它不允许根据需要从远程服务器上“拉”来消息。
SMTP服务器就是遵循SMTP协议的发送邮件服务器,SMTP认证就是要求必须在提供了账户名和密码之后才可以登录 SMTP 服务器,
这就使得那些垃圾邮件的散播者无可乘之机。  

SMTP 的全称是“Simple Mail Transfer Protocol”,即简单邮件传输协议。
它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。SMTP 协议属于 TCP/IP 协议簇,
它帮助每台计算机在发送或中转信件时找到下一个目的地。SMTP 服务器就是遵循 SMTP 协议的发送邮件服务器。
(SMTP 认证,简单地说就是要求必须在提供了账户名和密码之后才可以登录 SMTP 服务器,这就使得那些垃圾邮件的散播者无可乘之机。
增加 SMTP 认证的目的是为了使用户避免受到垃圾邮件的侵扰。)

Google Gmail

IMAP, SMTP, POP3 得設定值, 整理如下:

IMAP

  • imap.gmail.com
  • Port: 993
  • Use SSL: Yes

SMTP

  • smtp.gmail.com
  • Port for TLS/STARTTLS: 587
  • Port for SSL: 465

POP3

  • pop.gmail.com
  • Port: 995
  • Use SSL: Yes

阿里云邮箱已经支持POP3收信和SMTP发信功能,默认已开启。阿里云邮箱服务器信息:

服务器名称服务器地址服务器端口号(非加密)服务器端口号(SSL加密)
POP3pop3.aliyun.com110995
SMTPsmtp.aliyun.com25465
IMAPimap.aliyun.com143993

腾讯企业邮箱

如何设置IMAP、POP3/SMTP及其SSL加密方式?

 如果您的电子邮件客户端支持SSL,可以在设置中选择使用SSL。 通用配置参数:(我们已经默认都支持这些协议,用户无需自己手动开启这些服务器与端口)POP3/SMTP协议接收邮件服务器:pop.exmail.qq.com ,使用SSL,端口号995发送邮件服务器:smtp.exmail.qq.com ,使用SSL,端口号465海外用户可使用以下服务器接收邮件服务器:hwpop.exmail.qq.com ,使用SSL,端口号995发送邮件服务器:hwsmtp.exmail.qq.com ,使用SSL,端口号465 IMAP协议接收邮件服务器:imap.exmail.qq.com  ,使用SSL,端口号993发送邮件服务器:smtp.exmail.qq.com ,使用SSL,端口号465海外用户可使用以下服务器接收邮件服务器:hwimap.exmail.qq.com ,使用SSL,端口号993发送邮件服务器:hwsmtp.exmail.qq.com ,使用SSL,端口号465 账户名:您的企业邮箱账户名,账户名需要填写完整的邮件地址密码:您的企业邮箱密码电子邮件地址:您的企业邮箱的完整邮件地址 

腾讯QQ邮箱

POP3:pop.qq.com 
SMTP:smtp.qq.com 
IMAP:imap.qq.com 端口:143 

网易163免费邮箱

相关服务器信息:

网易邮箱已经默认开启 POP3/SMTP/IMAP 服务,方便您可以通过电脑客户端软件更好地收发邮件,如果关闭可以通过以下方式开启:

请登录163邮箱,点击页面正上方的“设置”,再点击左侧上“POP3/SMTP/IMAP”,其中“开启SMTP服务”是系统默认勾选开启的。

您可勾选图中另两个选项,点击确定,即可开启成功。不勾选图中两个选项,点击确定,可关闭成功。

IMAP收件服务器地址:imap.163.com       安全类型:SSL     端口号:993

注:1、126邮箱的IMAP服务器地址:imap.126.com ,yeah邮箱的IMAP服务器地址:imap.yeah.net ;

    2、若安全类型选择“无”,则需将端口号修改为 143。

SMTP发件服务器地址:smtp.163.com        安全类型:SSL     端口号:465 / 994 

注:1、126邮箱的SMTP服务器地址:smtp.126.com ,yeah邮箱的SMTP服务器地址:smtp.yeah.net;

    2、若安全类型选择“无”,则需将端口号修改为 25。

POP3收件服务器地址:pop.163.com       端口号:110

(注:126邮箱的POP3服务器地址:pop.126.com ,yeah邮箱的POP3服务器地址:pop.yeah.net ,端口号都是:110) 

SMTP发件服务器地址:smtp.163.com         端口号:25

(注:126邮箱的SMTP服务器地址:smtp.126.com ,yeah邮箱的SMTP服务器地址:smtp.yeah.net ,端口号都是:25) 

263.net:

POP3服务器地址:pop3.263.net
SMTP服务器地址:smtp.263.net

x263.net:

POP3服务器地址:pop.x263.net
SMTP服务器地址:smtp.x263.net

263.net.cn:

POP3服务器地址:pop.263.net.cn
SMTP服务器地址:smtp.263.net.cn

21cn.com:

POP3服务器地址:pop.21cn.com
SMTP服务器地址:smtp.21cn.com

sina.com:

POP3服务器地址:pop3.sina.com.cn
SMTP服务器地址:smtp.sina.com.cn

tom.com:

POP3服务器地址:pop.tom.com
SMTP服务器地址:smtp.tom.com

elong.com:

POP3服务器地址:pop3.elong.com
SMTP服务器地址:smtp.elong.com

china.com:

POP3服务器地址:pop.china.com
SMTP服务器地址:smtp.china.com

sohu.com:

POP3服务器地址:pop3.sohu.com
SMTP服务器地址:smtp.sohu.com

etang.com:

POP3服务器地址:pop.etang.com
SMTP服务器地址:smtp.etang.com

yahoo.com:

POP3服务器地址:pop.mail.yahoo.com
SMTP服务器地址:smtp.mail.yahoo.com

yahoo.com.cn:

POP3服务器地址:pop.mail.yahoo.com.cn
SMTP服务器地址:smtp.mail.yahoo.com.cn移动139邮箱 POP3:pop.139.com SMTP:smtp.139.com   天翼189邮箱 POP3:pop.189.cn SMTP:smtp.189.cn   163邮箱 POP3:pop.163.com SMTP:smtp.163.com   163Vip邮箱 POP3:pop.vip.163.com SMTP:smtp.vip.163.com   126邮箱 POP3:pop3.126.com SMTP:smtp.126.com   Gmail POP3:pop.gmail.com SMTP:smtp.gmail.com IMAP:imap.gmail.com 端口:995 465 993   Yahoo邮箱 POP3:pop.mail.yahoo.com SMTP:smtp.mail.yahoo.com   Hotmail POP3:pop3.live.com SMTP:smtp.live.com 端口:995   Sogou邮箱 POP3:pop3.mail.sogou.com SMTP:smtp.mail.sogou.com 邮箱Foxmial ,Outlook等客户端设置

            网易邮箱 POP3 和 SMTP 服务器地址设置如下:

            邮箱 POP3 服务器(端口110) SMTP 服务器(端口25) 

            @163.com、 pop3.163.com、 smtp.163.com 

            @126.com 、pop3.126.com 、smtp.126.com 

            @netease.com、 pop.netease.com、 smtp.netease.com 

            @yeah.net 、pop.yeah.net 、smtp.yeah.net 

            所有的SMTP服务器都需要身份验证。

            Sina免费邮件服务器设置 

            收信(pop3)服务器:pop3.sina.com.cn

            发信(smtp)服务器:smtp.sina.com.cn

            请选择smtp服务器要求身份验证选项

            Yahoo中国免费邮件服务器设置:

            接收邮件(POP3)服务器:pop.mail.yahoo.com.cn

            发送邮件(SMTP)服务器:smtp.mail.yahoo.com.cn

            Yahoo免费邮件服务器设置:(把你的资料填成国外的)

            接收邮件(POP3)服务器:pop.mail.yahoo.com

            发送邮件(SMTP)服务器:smtp.mail.yahoo.com

            Gmail客户端:

            POP服务器:pop.gmail.com

            打开ssl端口995(注意,pop得默认端口是110,在这里要改成995)

            SMTP服务器:smtp.gmail.com 

            smtp服务器需要身份验证

            开启ssl端口465或587

            帐户名:你得gmail用户名(包括 ‘@gmail.com‘这部分)

            Email地址:你得完整得gmail地址(username@gmail.com)

            密码:你得gmail密码

            中华网 

            pop.china.com

            smtp.china.com 

            搜狐 

            pop.sohu.com 

            smtp.sohu.com

            163电子邮局 

            163.net

            smtp.163.net 

            263电子邮局 

            263.net 

            smtp.263.net

            QQ邮箱不提供POP3服务

            Hotmail邮箱不提供POP3和SMTP服务

                   163.net收费邮箱

                   popx.163vip.net

                   smtp.163vip.net 

常用邮箱POP3和SMTP服务器设置

【网易 163、126免费邮箱目前不直接开放smtp、pop3服务。有需要的用户可通过购买随身邮或邮箱伴侣及加入会员中心获得。从2006年11月16日起新注册用户,将无法使用POP客户端功能,之前注册用户不受影响。】 

网易163邮箱

POP3:pop.163.com

SMTP:smtp.163.com

SMTP端口号:25 

网易vip.163邮箱

POP3:pop.vip.163.com

SMTP:smtp.vip.163.com

SMTP端口号:25  

网易126邮箱

POP3:pop.126.com

SMTP:smtp.126.com

SMTP端口号:25 

网易188邮箱

POP3:pop.188.com

SMTP:smtp.188.com

SMTP端口号:25 

网易yeah.net邮箱

POP3:pop.yeah.net

SMTP:smtp.yeah.net

SMTP端口号:25 

网易netease.com邮箱

POP3:pop.netease.com

SMTP:smtp.netease.com

SMTP端口号:25

【新浪 需登陆web邮箱,设置-账户,开通smtp/pop服务,如是VIP,请务必勾选“smtp服务器要求身份验证”一项】 

新浪免费邮箱

POP3:pop.sina.com

SMTP:smtp.sina.com

SMTP端口号:25

新浪VIP邮箱

POP3:pop3.vip.sina.com

SMTP:smtp.vip.sina.com

SMTP端口号:25

新浪企业邮箱

POP3:pop.sina.com

SMTP:smtp.sina.com

SMTP端口号:25

【yahoo在foxmail 4.1以上的版本设置如下:( outlook 不行)需订制“来电提醒”服务,不定制此项服务,将无法使用POP服务。】

雅虎邮箱

POP3:pop.mail.yahoo.cn

SMTP:smtp.mail.yahoo.cn

SMTP端口号:25

【搜狐 TOM 规则较多,容易被封账号】

搜狐邮箱

POP3:pop3.sohu.com

SMTP:smtp.sohu.com

 SMTP端口号:25

TOM邮箱

POP3:pop.tom.com

SMTP:smtp.tom.com

 SMTP端口号:25

【谷歌 需要勾选启用SSL,465端口好像服务器端被封掉了】

Gmail邮箱

POP3:pop.gmail.com

SMTP:smtp.gmail.com

 SMTP端口号:587 或 25

【需登陆web邮箱,设置-帐户,开通smtp/pop服务;设置完成后,请务必勾选“smtp服务器要求身份验证”一项。
        邮箱开通15天后才可开通smtp服务。】

QQ邮箱

POP3:pop.qq.com

SMTP:smtp.qq.com

SMTP端口号:25

263邮箱

域名:263.net

POP3:263.net

SMTP:smtp.263.net

SMTP端口号:25

域名:x263.net

POP3:pop.x263.net

SMTP:smtp.x263.net

SMTP端口号:25

域名:263.net.cn

POP3:263.net.cn

SMTP:263.net.cn

SMTP端口号:25

域名:炫我型

POP3:pop.263xmail.com

SMTP:smtp.263xmail.com

SMTP端口号:25

21CN  免费邮箱

POP3:pop.21cn.com

SMTP:smtp.21cn.com

IMAP:imap.21cn.com

SMTP端口号:25

21CN  经济邮邮箱

POP3:pop.21cn.com

SMTP:smtp.21cn.com

SMTP端口号:25

21CN  商务邮邮箱

POP3:pop.21cn.net

SMTP:smtp.21cn.net

SMTP端口号:25

21CN  快感邮箱

POP3:vip.21cn.com

SMTP:vip.21cn.com

SMTP端口号:25

21CN  Y邮箱

POP3:pop.y.vip.21cn.com

SMTP:smtp.y.vip.21cn.com

SMTP端口号:25

中华网任我邮邮箱

POP3:rwpop.china.com

SMTP:rwsmtp.china.com

 SMTP端口号:25 

中华网时尚、商务邮箱

POP3:pop.china.com

SMTP:smtp.china.com

SMTP端口号:25

各种常用邮箱POP3/SMTP/IMAP

发表于2012 年 3 月 5 日

1.gmail

gmail服务器地址非SSLSSL
IMAPimap.gmail.com –993
POPpop.gmail.com –995
SMTPssl://smtp.gmail.com –465

2.139邮箱

139邮箱服务器地址非SSLSSL
IMAPimap.10086.cn143
POPpop.10086.cn110995
SMTPsmtp.10086.cn25465

3.163邮箱

163邮箱服务器地址非SSLSSL
IMAPimap.163.com143993
POPpop.163.com110995
SMTPsmtp.163.com25465/994

4.qq邮箱

qq邮箱服务器地址非SSLSSL
IMAPimap.qq.com143993
POPpop.qq.com110995
SMTPsmtp.qq.com25465/587

5.sina邮箱

sina邮箱服务器地址非SSLSSL
IMAPimap.sina.com143993
POPpop.sina.com110
SMTPsmtp.sina.com25

@sina.com
POP3服务器地址:pop3.sina.com.cn
SMTP服务器地址:smtp.sina.com.cn

@sohu.com
POP3服务器地址:pop3.sohu.com
SMTP服务器地址:smtp.sohu.com

@yeah.net
POP3服务器地址:pop3.yeah.net
SMTP服务器地址:smtp.yeah.net

@126.com
POP3服务器地址:pop3.126.com
SMTP服务器地址:smtp.126.com

@163.com
POP3服务器地址:pop.163.com
SMTP服务器地址:smtp.163.com

@tom.com
POP3服务器地址:pop.tom.com
SMTP服务器地址:smtp.tom.com

@263.net
POP3服务器地址:pop.263.net
SMTP服务器地址:smtp.263.net

@21cn.com
POP3服务器地址:pop.21cn.com
SMTP服务器地址:smtp.21cn.com
SMTP服务器地址:imap.21cn.com

@yeahoo.com.cn
POP3服务器地址:pop.mail.yahoo.com.cn
SMTP服务器地址:smtp.mail.yahoo.com.cn

@eyou.com
POP3服务器地址:pop3.eyou.com
SMTP服务器地址:mx.eyou.com

以上所有smtp服务器都要求身份验证


@Gmail

POP3服务器地址: pop.gmail.com

端口:995

支持SSL

SMTP服务器地址: smtp.gmail.com

端口:465

支持SSL(TSL)

邮箱名称POP地址SMTP地址IMAP地址POP端口SMTP端口IMAP端口
 188 邮箱pop.188.comsmtp.188.comimap.188.com110/995465/994/25143/993
  163 邮箱pop.163.comsmtp.163.comimap.163.com110/995465/994/25143/993
  126 邮箱pop.126.comsmtp.126.comimap.126.com11025143
  netease 邮箱pop.netease.comsmtp.netease.comimap.netease.com110/995465/587/25143/993
  yeah 邮箱pop.yeah.netsmtp.yeah.netimap.yeah.net110/995465/587/25143/993
  QQ  邮箱pop.qq.comsmtp.qq.comimap.qq.com110/995465/587/25143/993
  Gmail  邮箱pop.gmail.comsmtp.gmail.comimap.gmail.com110/995465/25993
  Sina  邮箱pop.sina.com.cnsmtp.sina.com.cnimap.sina.com.cn11025993
  sohu  邮箱pop3.sohu.comsmtp.sohu.comimap.sohu.com11025993
  TOM  邮箱pop3.tom.comsmtp.tom.comimap.tom.com11025993
  • 163邮箱支持IMAP和POP两种协议,账户名为包含@的网站邮件地址
类型服务器名称服务器地址SSL协议端口号非SSL协议端口号备注
收件服务器POPpop.163.com995110
收件服务器IMAPimap.163.com993143
发件服务器SMTPsmtp.163.com465/99425需要身份验证
  • QQ邮箱支持IMAP和POP两种协议以及EXCHANGE同步服务,需要再QQ邮箱的WEB版实验室选项里开通账户名为QQ邮箱账户名(@前的部分,如果您是VIP帐号或Foxmail帐号,账户名需要填写完整的邮件地址)
类型服务器名称服务器地址SSL协议端口号非SSL协议端口号备注
收件服务器POPpop.qq.com995110
收件服务器IMAPimap.qq.com993143
发件服务器SMTPsmtp.qq.com465/58725需要身份验证
EXCHANGE同步exchangeex.qq.com用户名为完整EMAIL地址
  • gmail邮箱支持IMAP和POP两种协议以及EXCHANGE同步服务,需要再网页邮箱的设置中先开通。账户名为包含@的网站邮件地址
类型服务器名称服务器地址SSL协议端口号非SSL协议端口号备注
收件服务器POPpop.gmail.com995N/A
收件服务器IMAPimap.gmail.com993N/A
发件服务器SMTPsmtp.gmail.com465/58725要求TLS,需要身份验证
EXCHANGE同步exchangem.google.com用户名为完整EMAIL地址
  • 阿里巴巴内网云邮箱支持IMAP和POP3两种协议以及EXCHANGE同步服务,账户名为包含@的网站邮件地址,更多信息,参考http://alimail.alibaba-inc.com/help/
类型服务器名称服务器地址SSL协议端口号非SSL协议端口号备注
收件服务器POPpop3.alibaba-inc.com995N/A SSL
收件服务器IMAPimap.alibaba-inc.com993N/A SSL
发件服务器SMTPsmtp.alibaba-inc.com465N/A要求SSL,需要身份验证
EXCHANGE同步exchangeex.alibaba-inc.com用户名为完整EMAIL地址
LDAP通讯簿服务器LDAPldap.alibaba-inc.com636N/A用户名为完整EMAIL地址
日历服务器caldavcaldav.alibaba-inc.com443 N/A用户名为完整EMAIL地址 

【酷站推荐】-快易数据-

GHOST阅读(54)

需要历来的各国经济数据(经济与增长、人口、国土资源等)感兴趣的可以参考下,不是最新但至少很全面,界面干净。

经济与增长

人口构成

国土资源

.htaccess设置伪静态后做全站301

GHOST阅读(55)

.htaccess文件里可以设置伪静态,但是你网站进行伪静态后,这样网站就会出现两个url,动态和静态,为了集中权重和用户体验,最好两个url整合在一起,这样就需要进行全站301了。

问题描述:网站程序asp.net,动态url太长,超过百度搜索框最大长度限制,用户体验差,需要进行url优化。

解决方法:对网站url进行伪静态并进行全站301。

实现过程:

1、空间或者服务器必须支持伪静态在.htaccess文件里实现,一般Linux服务器或者配置IIS6+ISAPI Rewrite 3.X的windows服务器都可以。

2、找到网站的url规则然后在.htaccess文件里设置301伪静态,测试后伪静态生效。

3、然后进行全站301永久重定向的书写,发现写好301规则后,访问伪静态的url出现404,通过各种方式以及网上搜集资料都没有找到解决方法,后来我单独尝试做301发现问题解决,同时伪静态也生效(不需要单独做伪静态)。下面来分享一下实现的代码:

网站域名:www.changgentang.com

原始url规则之一:/mediareport.aspx?c_kind=22&c_kind2=23&id=491

转换后url为:/news-22-23-491.html

这里列举几条实现全站301永久重定向的规则,其他都是通用:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
 
//一个变量设置全站301
RewriteRule ^sitemap-([0-9]+).html$ /sitemap.aspx?c_kind=$1&r=1 [L]
RewriteCond %{QUERY_STRING} ^c_kind=([0-9]+)$ [NC]
RewriteRule ^sitemap.aspx?$ /sitemap-%1.html? [L,R=301]
 
//二个变量设置全站301
RewriteRule ^news-([0-9]+)-([0-9]+).html$ /mediareport.aspx?c_kind=$1&c_kind2=$2&r=1 [L]
RewriteCond %{QUERY_STRING} ^c_kind=([0-9]+)&c_kind2=([0-9]+)$ [NC]
RewriteRule ^mediareport.aspx?$ /news-%1-%2.html? [L,R=301]
 
//三个变量设置全站301
RewriteRule ^zixun-([0-9]+)-([0-9]+)-([0-9]+).html$ /message_detail.aspx?c_kind=$1&c_kind2=$2&id=$3&r=1 [L]
RewriteCond %{QUERY_STRING} ^c_kind=([0-9]+)&c_kind2=([0-9]+)&id=([0-9]+)$ [NC]
RewriteRule ^message_detail.aspx?$ /zixun-%1-%2-%3.html? [L,R=301]
 
</IfModule>

Flutter-从入门到愉快玩耍!

GHOST阅读(60)

Flutter-从入门到愉快玩耍!

前言

毕竟前端出生,找(qi)到(shi)了(bing)感(mei)觉(ru)后(men),其实就是一个UI框架,只不过他的引擎基于C++,底层基于Skia渲染,DartVM虚拟机以及Text and so on…

2018年6月21日Google发布Flutter首个release预览版,作为Google baba大力推出的一种全新的响应式,跨平台,高性能的移动开发框架,势必会火一波~没别的,就是因为Google baba,当然,从目前看来也的确越来越火了。
[Questions tagged [flutter]](https://stackoverflow.com/que…

本文我们从介绍flutter基本概念到梳理常用Widget到常用app demos编写到~放弃~,希望可以帮助每一个像我一样的初学者。有误地方还望大神不吝赐教~

国际惯例,吹一波先~

直接移步Flutter官宣ppt

关于Dart

作为Flutter入门文章,Dart必然少不了,当然,作为Flutter入门篇,Dart预发基础必然不会过多介绍。

Dart入门传送门:Dart or Dart2,或者从Dart中文网中学习也不错其实.

这里我们说说为啥是Dart。

许多语言科学家认为,一个人说的自然语言会影响他们的思维方式。早起Flutter团队评估了十多种语言最终选择了Dart,因为它符合他们构建用户界面的方式

  • Dart 是AOT 编译的,编译成快速可预测的本地代码,使Flutter几乎都可以使用Dart编写,这不仅使Flutter变的更快,而且几乎所有的东西都可以定制
  • Dart也可以JIT编译,开发周期异常快,工作流颠覆常规,也使得Flutter可以实现非常Diao的有状态热重载(别扯别的,人家是出生自带哇)
  • Dart可以更轻松地创建以60fps运行的流畅动画和转场。Dart可以在没有锁的情况下进行对象分配和垃圾回收。就像JavaScript一样,Dart避免了抢占式调度和共享内存(因而也不需要锁)。由于Flutter应用程序被编译为本地代码,因此它们不需要在领域之间建立缓慢的桥梁(例如,JavaScript到本地代码)。它的启动速度也快得多
  • Dart使Flutter不需要单独的声明式布局语言,如JSX或XML,或单独的可视化界面构建器,因为Dart的声明式编程布局易于阅读和可视化。所有的布局使用一种语言,聚集在一处,Flutter很容易提供高级工具,使布局更简单
  • Dart对于IOS、Android、Web FE来说,都还比较友好。

具体选择Dart的原因,以及向了解Dart的,移步为什么Flutter会选择 Dart

关于Flutter

刚开始接触flutter心中难免会有疑惑,不是已经有RN、Weex等各种跨平台移动开发 了,flutter优势在哪呢? 看我从网上盗的图!

图片来源简书

Everything is Widget

有一种说法认为函数式语言和命令式语言的不同在于命令式语言是给计算机下达指令而函数式语言是向计算机描述逻辑。这种思路在Flutter UI中得到了体现。Flutter不提倡去操作UI,它当然也基本不会提供操作View的API,比如我们常见的类似TextView.setText(),Button.setOnClick()这种是不会有的。对界面的描述是可以数据化的(类似XML,JSON等),而对界面的操作是很难数据化的,这很重要,响应式需要方便可持续的将数据映射成界面。

在Flutter中用Widget来描述界面,Widget只是View的“配置信息”,编写的时候利用Dart语言一些声明式特性来得到类似结构化标记语言的可读性。Widget根据布局形成一个层次结构。每个widget嵌入其中,并继承其父项的属性。没有单独的“应用程序”对象,相反,根widget扮演着这个角色。在Flutter中,一切皆为Widget,甚至包括css样式。

<div class="greybox">
    Lorem ipsum
</div>

.greybox {
      background-color: #e0e0e0; /* grey 300 */
      width: 320px;
      height: 240px;
      font: 900 24px Georgia;
    }

在flutter中我们编写为

var container = new Container( // grey box
  child: new Text(
    "Lorem ipsum",
    style: new TextStyle(
      fontSize: 24.0
      fontWeight: FontWeight.w900,
      fontFamily: "Georgia",
    ),
  ),
  width: 320.0,
  height: 240.0,
  color: Colors.grey[300],
);

可以看到我们css样式中的font定义的样式,在flutter中,需要new TextStyleTextStyle就是一个Widget,并且样式必须作用与Container中的child:text上,不存在web中样式的继承。

刚开始接触的同学就类比于react中扯的,一切皆为组件吧,其实widget是对页面UI的一种描述。他功能类有点似于android中的xml,react中的jsx。widget在渲染的时候会转化成element。Element相比于widget增加了上下文的信息。element是对应widget,在渲染树的实例化节点。由于widget是immutable的,所以同一个widget可以同时描述多个渲染树中的节点。但是Element是描述固定在渲染书中的某一个特定位置的点。简单点说widget作为一种描述是可以复用的,但是element却跟需要绘制的节点一一对应。那element是最终渲染的view么?抱歉,还不是。element绘制时会转化成rendObject。RendObject才是真正经过layout和paint并绘制在屏幕上的对象。在flutter中有三套渲染相关的tree,分别是:widget tree, element tree & rendObject tree。三者的渲染流程如下:

有没有一种 jsx -> virtual Dom -> real dom滴感觉呢~

咳咳,后面会介绍基础常用的Widget配合一些demo,大家可能对这个体会就会更加清晰一些。

组合大于继承

Flutter中很多借鉴了react的思想,甚至包括后面会说到的state。

Widget本身通常由许多更小的、单一的小小widget组成,甚至小到它单一下来并没有什么作用的感觉,这些Widget几几组合形成一个强大的自定义的大大Widget。

比如一个Container,对于Web FE来说可能就是个div,而他就是由很多的widget组成,这些widget负责布局、绘制、定位、大小等。我们可以使用各种姿势来组合他们而不是继承他们。类层次结构很浅且很宽,可以最大限度的增加可能组合的数量

框架结构


上面的图片是Flutter分层框架结构图,对大部分开发者而言,最常用的是Widgets层,屏幕上可见与不可见的元素都由Widgets层实现,这些元素被称为Widget。在Widgets层在上层,有两个现成的Widget库,Material库即Material Design的Widget库,Material Design是Google I/O 2014发布的设计语言,目前成为统一Android Mobile、Android Table、Desktop Chrome等平台的设计语言规范。Cupertino库则是一个模仿iOS设计风格的Widget库。

底层是Flutter Engine虚拟机,在这一层次中需要了解一下的是Skia,Skia是Google研发的包括图形、文本、图像、动画等多方面的图形引擎,不仅用于Google Chrome浏览器,Android系统也采用Skia作为绘图处理引擎。

GPU渲染:

state生命周期:

作为初学者看上面的图有点云里雾里的,且先做到心里有数~

Flutter走马观花

关于Flutter环境问题这里不再赘述
此后~大量代码来袭

基础Widget之material版Hello world

国际惯例,hello world

import 'package:flutter/material.dart';

class MyAppBar extends StatelessWidget{
  MyAppBar({this.title});//
  final Widget title;

  @override
  Widget build(BuildContext context){
    return new Container(
      height: 56.0,
      padding: const EdgeInsets.symmetric(horizontal:8.0),
      decoration: new BoxDecoration(
        color:Colors.blue[400]
      ),
      child: Row(
        children: <Widget>[
          new IconButton(
            icon:new Icon(Icons.menu),
            tooltip:'Navigation menu',
            onPressed: (){
              print('点击Menu');
            },
          ),
          new Expanded(
            child:new Center(
              child:title
            )
          ),
          new IconButton(
            icon:Icon(Icons.search),
            tooltip:'Search',
            onPressed: (){
              print('点击搜索按钮');
            },
          )
        ],
      ),
    );
  }
}

class MyScaffold extends StatelessWidget{
  @override 
  Widget build(BuildContext context){
    return Material(
      child: new Column(
        children:<Widget>[
          new MyAppBar(
            title:new Text(
              'Hello World',
              style:Theme.of(context).primaryTextTheme.title
             ),
          ),
          new Expanded(
            child:new Center(
              child:Text('Hello World!!!')
            )
          )
        ]
      ),
    );
  }
}

void main(){
  runApp(
    new MaterialApp(
      title:'My app',
      home:new MyScaffold()
    )
  );
}


代码地址:https://github.com/Nealyang/flutter

这个UI的确有些对不起人了,上面的title被挡住了。且先不去适配,后面我们使用Material提供的Scaffold即可

第一个例子,重点说下代码(用过的Widget记住):

  • 一切都是Widget,且Widget前面的new可有可无。
  • 类MyAppBar和MyScaffold中使用了Container、Row、Column、Text、IconButton、Icon、BoxDecoration、Center、Expanded等常用Widget

    • Container一个拥有绘制、定位、调整大小的 widget。类似于div,我们可以用它来创建矩形视图,container 可以装饰为一个BoxDecoration, 如 background、一个边框、或者一个阴影。 Container 也可以具有边距(margins)、填充(padding)和应用于其大小的约束(constraints)。另外, Container可以使用矩阵在三维空间中对其进行变换。
    • RowColumn其实就是flex布局中的flex-direction
    • Expanded它会填充尚未被其他子项占用的的剩余可用空间。Expanded可以拥有多个children。然后使用flex参数来确定他们占用剩余空间的比例。更多细节可以参看:flutter控件Flexible和 Expanded的区别
  • 先定义了一个MyAppBar的类,构造函数中接受一个Widget的title,其实我们也可以接受String title然后在类中自己去new Title(title)
  • runApp函数接受给定的Widget并使用其作为widget根。
  • widget的主要工作是实现一个build函数,用以构建自身。一个widget通常由一些较低级别widget组成。Flutter框架将依次构建这些widget,直到构建到最底层的子widget时,这些最低层的widget通常为RenderObject,它会计算并描述widget的几何形状。

基本交互之material版Hello world

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  // app的根Widget
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        // 这是设置的app主题
        // 运行后你可以看到app有一个蓝色的toobar,并且在不退出app的情况下修改代码会热更新
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

// 这是应用中一个基类,继承自StateFulWidget,意味着这个类拥有一个state对象,该对象里的一些字段会影响app的UI
// 这个类是state的一些配置项。通过构造函数来获取值,这个值一般在State中消费,并且使用final关键字。其实类似于react中的defaultProps

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      // setState方法告诉Flutter,这个State中有些值发生了变化,以便及时将新值更新到UI上,
      // 如果我不通过setState更改_count字段,那么Flutter并不会调用build匿名函数去更新界面
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    // build方法会在每次setState的时候重新运行,例如上面的_incrementCounter方法被调用
    //Flutter已经被优化了重新构建的方法,所以你只会去更新需要去更新的部分,不必去单独更新里面的一些更细小的widget,类似于React中diff
    return new Scaffold(
      appBar: new AppBar(
        // 这里我们使用从App.build方法中初始化MyHomePage时候传入的title值来设置我们的title
        title: new Text(widget.title),
      ),
      body: new Center(
        // Center是一个布局Widget,他只有一个child(区分row or cloumn等是children),并且会将child的widget居中显示
        child: new Column(
          // Column也是一个布局widget,他可以有多个子widget
          // Column 有很多的属性去控制他的大小以及子widget的位置,这里我们使用mainAxisAlignment来让children在垂直线上居中,
          // 这里的主轴就是垂直的,因为Column就是垂直方向的,这里可以大概想象为display:flex,flex-directions:column,align-item,justifyContent。。。
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'Hello World!',
              style:TextStyle(
                fontSize:24.0,
                color: Colors.redAccent,
                decorationStyle:TextDecorationStyle.dotted,
                fontWeight: FontWeight.bold,
                fontStyle: FontStyle.italic,
                decoration: TextDecoration.underline
              )
            ),
            new Text(
              'You have pushed the button this many times:',
            ),
            new Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ),//最后这个逗号有利于格式化代码
    );
  }
}

img
注释上基本已经加了,这里重点说下,StatefulWidget和StatelessWidget.

  • Stateless widgets 是不可变的,这意味着它们的属性不能改变——所有的值都是 final
  • Stateful widgets 持有的状态可能在 widget 生命周期中发生变化,实现一个 stateful widget 至少需要两个类:1)一个 StatefulWidget 类;2)一个 State 类,StatefulWidget 类本身是不变的,但是 State 类在 widget 生命周期中始终存在
  • 如果需要变化需要重新创建。StatefulWidget可以保存自己的状态。那问题是既然widget都是immutable的,怎么保存状态?其实Flutter是通过引入了State来保存状态。当State的状态改变时,能重新构建本节点以及孩子的Widget树来进行UI变化。注意:如果需要主动改变State的状态,需要通过setState()方法进行触发,单纯改变数据是不会引发UI改变的。

还有关于key的部分这里就不做介绍了,其实就类似与react中key的概念,便于diff,提高效率的。
具体可以查看 Key

到这里,我们看到了Flutter的一些基本用法,Widget的套用、样式的编写、事件的注册,如果再学习下一些路由、请求、缓存是不是就可以自己开发APP了呢img

OK,强化下编写界面,咱再来些demo吧~

布局Widget

img

自己写的后,发现跟官网实现方式不同,代码地址

具体实现可以参照官网教程

这里不再赘述,下面我们说下对于布局的理解和感受以及常用布局widget。

从一个前端的角度来说,说到画界面,可能还是对布局这块比较敏感

img

img)

当然,这里我们还是说下目前常用的flex布局,基本拿到页面从大到小拆分后就是如上图。

所以Widget布局其实也就是Row和Column用的最多,然后由于Flutter一切皆为组件的理念,可能会需要用到别的类css布局的Widget,譬如:Container。其实咱就理解为块元素吧!

下面简单演示下一些常用的Widget,这里就不在赘述Row和Column了。传送门:布局Widget

Container

可以添加padding、margin、border、background color、通常用于装饰其他Widget

img

代码链接 Nealyang/flutter

class MyHomePage extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    Container cell (String imgSrc){
      return new Container(
        decoration: new BoxDecoration(
          border:Border.all(width:6.0,color:Colors.black38),
          borderRadius: BorderRadius.all(const Radius.circular(8.0))
        ),
        child: Image.asset(
          'images/$imgSrc',
          width: 180.0,
          height: 180.0,
          fit: BoxFit.cover,
        ),
      );
    }

    return Container(
      padding: const EdgeInsets.all(10.0),
      color: Colors.grey,
      child: new Column(
        mainAxisSize: MainAxisSize.min,
        children:<Widget>[
          new Container(
            margin: const EdgeInsets.only(bottom:10.0),
            child: new Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children:<Widget>[
                cell('1.jpg'),
                cell('2.jpg')
              ]
            ),
          ),
          new Container(
            margin: const EdgeInsets.only(bottom:10.0),
            child: new Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children:<Widget>[
                cell('3.jpg'),
                cell('4.jpg')
              ]
            ),
          ),
        ]
      ),
    );
  }
}

该布局中每个图像使用一个Container来添加一个圆形的灰色边框和边距。然后使用容器将列背景颜色更改为浅灰色。

GridView

可滚动的网格布局,理解为display:grid

GridView提供两个预制list,当GridView检测到内容太长时,会自动滚动。如果需要构建自定义grid,可是使用GridView.count或 GridView.extent来指定允许设置的列数以及指定项最大像素宽度。

img

代码链接 Nealyang/flutter

List<Container> _buildGridTileList(int count) {

  return new List<Container>.generate(
      count,
      (int index) =>
          new Container(child: new Image.asset('images/${index+1}.jpg')));
}

Widget buildGrid() {
  return new GridView.extent(
      maxCrossAxisExtent: 150.0,
      padding: const EdgeInsets.all(4.0),
      mainAxisSpacing: 4.0,
      crossAxisSpacing: 4.0,
      children: _buildGridTileList(10));
}

class MyHomePage extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return  new Center(
        child: buildGrid(),
      );
  }
}

如上是指定maxCrossAxisExtent,我们可以直接去指定列数,例如官网的代码实例:

new GridView.count(
  primary: false,
  padding: const EdgeInsets.all(20.0),
  crossAxisSpacing: 10.0,
  crossAxisCount: 3,
  children: <Widget>[
    const Text('He\'d have you all unravel at the'),
    const Text('Heed not the rabble'),
    const Text('Sound of screams but the'),
    const Text('Who scream'),
    const Text('Revolution is coming...'),
    const Text('Revolution, they...'),
  ],
)

通过crossAxisCount直接指定列数。

Stack

层叠布局,position为absolute的感jio~

使用Stack来组织需要重叠的widget。widget可以完全或部分重叠底部widget。子列表中的第一个widget是base widget; 随后的子widget被覆盖在基础widget的顶部。Stack的内容不能滚动。有点类似于weex中的设置了absolute的感觉。底部组件永远在上面组件的上面。

ListView

可滚动的长列表,可以水平或者垂直。

Card

Material风格组件,卡片,AntD啥的组件库经常会出现的那种组件。

在flutter中,Card具有圆角和阴影,更改Card的elevation属性可以控制阴影效果。

ListTile

Material风格组件,我理解为常用的列表Item的样式,最多三行文字,可选的行前、行尾的图标

img

代码链接 Nealyang/flutter

总结

从目前我个人浅薄的Flutter技能来说,最大的困难可能是找不到合适的Widget去实现想要的布局或者效果,甚至包括css样式作用于那个Widget,譬如Opacity是一个widget而不是一个css样式~

所以对于Flutter,我们还是要多折腾,多些demo,类似网上很多仿xxxApp等~

对于画界面,更多的还可以参看下官网教程:Flutter for Web开发者

一切才刚刚开始

Flutter一切基于Widget,搞定widget就好比,搞定英语单词一样,单词、词组都贼6了还怕英语?

别急别急,借用张晟哥的图来给大家消消火气~

widgets

所以说,Flutter有一个庞大的组件体系,需要花费非常多的时间去梳理。

!更重要的是:多实践

本来最后一章是自己写的一个demo的讲解~

可惜时间评估不准确,漏评估了假期惰性。。。考虑篇幅,后面补上仿XXX的Demo吧~~

img

世界,您好!

GHOST阅读(68)

欢迎使用WordPress。这是您的第一篇文章。编辑或删除它,然后开始写作吧!