MySQL 数据库中日期与时间函数FROM_UNIXTIME(), UNIX_TIMESTAMP() - kobejayandy的专栏 - 博客频道 - CSDN.NET

mikel阅读(1192)

原文:http://my.oschina.net/uboluo/blog/157483#OSC_h2_5参考xiang

来源: MySQL 数据库中日期与时间函数FROM_UNIXTIME(), UNIX_TIMESTAMP() – kobejayandy的专栏 – 博客频道 – CSDN.NET

MySQL 数据库中日期与时间函数FROM_UNIXTIME(), UNIX_TIMESTAMP()

710人阅读 评论(0) 收藏 举报
分类:

1、FROM_UNIXTIME( unix_timestamp )
参数:通常是壹个十位的数字,如:1344887103
返回值:有两种,可能是类似 ‘YYYY-MM-DD HH:MM:SS’ 这样的字符串,也有可能是类似于 YYYYMMDDHHMMSS.uuuuuu 这样的数字,具体返回什么取决于该函数被调用的形式。

1 mySQLselect FROM_UNIXTIME(1344887103);
2 +---------------------------+
3 | FROM_UNIXTIME(1344887103) |
4 +---------------------------+
5 | 2012-08-14 03:45:03       |
6 +---------------------------+
7 1 row in set (0.00 sec)

 

 

2、FROM_UNIXTIME( unix_timestamp ,format ) 
参数 unix_timestamp :与方法 FROM_UNIXTIME( unix_timestamp ) 中的参数含义一样;
参数 format : 转换之后的时间字符串显示的格式;
返回值:按照指定的时间格式显示的字符串;

01 mySQLselect FROM_UNIXTIME(1344887103,'%Y-%M-%D %h:%i:%s');
02 +-----------------------------------------------+
03 | FROM_UNIXTIME(1344887103,'%Y-%M-%D %h:%i:%s') |
04 +-----------------------------------------------+
05 | 2012-August-14th 03:45:03                     |
06 +-----------------------------------------------+
07 1 row in set (0.00 sec)
08 mysql> select FROM_UNIXTIME(1344887103,'%Y-%m-%D %h:%i:%s');
09 +-----------------------------------------------+
10 | FROM_UNIXTIME(1344887103,'%Y-%m-%D %h:%i:%s') |
11 +-----------------------------------------------+
12 | 2012-08-14th 03:45:03                         |
13 +-----------------------------------------------+
14
15 1 row in set (0.00 sec)

 

1、UNIX_TIMESTAMP()

返回值:当前时间的UNIX格式数字串,或者说是 UNIX 时间戳(从 UTC 时间’1970-01-01 00:00:00’开始的秒数),通常为十位,如 1344887103。Java里面 new Date().getTime()得到的结果是13位的,而数据库转化的是10位的。

1 mysql> select unix_timestamp();
2 +------------------+
3 | unix_timestamp() |
4 +------------------+
5 |       1344887103 |
6 +------------------+
7 1 row in set (0.00 sec)

2、UNIX_TIMESTAMP( date )
参数:date 可能是个 DATE 字符串,DATETIME 字符串,TIMESTAPE 字符串,或者是一个类似于 YYMMDD 或者 YYYYMMDD 的数字串。
返回:从 UTC 时间’1970-01-01 00:00:00’开始到该参数之间的秒数。服务器将参数 date 解释成当前时区的壹个值并且将其转化成 UTC 格式的内部时间。客户端则可以自行设置当前时区。当 UNIX_TIMESTAMP() 用于壹个 TIMESTAMP 列时,函数直接返回内部时间戳的值;如果你传递壹个超出范围的时间到 UNIX_TIMESTAMP(),它的返回值是零。

01 mysql> SELECT UNIX_TIMESTAMP();
02 +------------------+
03 | UNIX_TIMESTAMP() |
04 +------------------+
05 |       1344888895 |
06 +------------------+
07 1 row in set (0.00 sec)
08
09 mysql> SELECT UNIX_TIMESTAMP('2012-08-14 16:19:23');
10 +---------------------------------------+
11 | UNIX_TIMESTAMP('2012-08-14 16:19:23') |
12 +---------------------------------------+
13 |                            1344932363 |
14 +---------------------------------------+
15 1 row in set (0.00 sec)

注意:如果你使用 UNIX_TIMESTAMP() 和 FROM_UNIXTIME() 来转换 TIMESTAMP 值与 Unix 时间戳的值,精度会丢失,因为这个映射在两个方向上不是一一对应的。比如说,由于本地时区的更改,有可能两个 UNIX_TIMESTAMP() 会映射到同壹个 Unix 时间戳的值。 FROM_UNIXTIME() 只会映射到原来的那个时间戳的值上。这里有个例子,在 CET 时区使用 TIMESTAMP:

Jar mismatch! Fix your dependencies的问题 - 学习飞翔 - 博客频道 - CSDN.NET

mikel阅读(933)

来源: Jar mismatch! Fix your dependencies的问题 – 学习飞翔 – 博客频道 – CSDN.NET

看到网上有说:

在开发Android项目的时候,有时需要引用多个项目作为library。在引用项目的时候,有时会出现“Jar mismatch! Fix your dependencies”错误。

这是因为两个项目的jar包(Android-support-v4.jar)不一致。 解决方法是把2个jar都删除,然后各自加上最新的jar包。

这个最新的jar包怎么加呢?

我先是按照别人说的右键项目–AndroidTools–Add Support Library分别加上最新的包,最后还是解决不了,不知道是什么原因,按道理是可行的啊……

然后我把这两个项目其中一个项目的v4jar包放到另外一个项目,还是不行……

最后我把其他项目中的v4jar包,拿出来分别放到这两个项目中去,就解决问题了……其实这种方法和上面两种方法的唯一区别可能就是v4jar包不太一样

Eclipse有些时候是有点奇怪啊……

导入别人的项目时,工程中不自动生成Android Dependencies的解决方式

mikel阅读(978)

今天遇到的奇怪问题是网上下载的demo导入第三方包运行后Android: NoClassDefFoundError的错误,原因是第三方的jar包并没有打包进apk里,运行是肯定要出错的。

网上百度了N久,都是说先移除之前的Libraries,再将lib更名为libs的做法。今天是遇到邪门了,照做还是运行报错。后来发现直接add的jar包还是放在Referenced Libraries里,ADT升级到17后就出现了Android Dependencies,但这是自动生成的。将名字改来改去工程删来删去也还是无济于事,不能把jar包导入Android Dependencies里apk里也不会打包进去。

纠结啊…..后来打开了工程下的.classpath的文件,对比那些正常的工程,终于发现在里面加一句话<classpathentry exported=”true” kind=”con” path=”com.android.ide.eclipse.adt.LIBRARIES”/>就可以解决,Refresh一下,顺便clean一下,OK,完成!

YYStock开源----iOS股票K线绘制第二版 - yate1996 - 博客园

mikel阅读(1591)

来源: YYStock开源—-iOS股票K线绘制第二版 – yate1996 – 博客园

新的股票绘制粗来啦,欢迎围观star的说(*^__^*) 嘻嘻……

捏合功能也准备完善了

Github:https://github.com/yate1996/YYStock

长按分时图+五档图

 

分时图+五档图

 

长按分时图

 

分时图

 

K线图

 

长按K线图

 

非全屏嵌入

 

咦,发现UI好看但是功能好像有点不够用???

没事,欲求不满的话专业版K线Demo也有♪(^∇^*) 戳这里:https://github.com/yate1996/Y_KLine

php函数serialize()与unserialize() - 编程的数学原理 - 博客频道 - CSDN.NET

mikel阅读(903)

来源: php函数serialize()与unserialize() – 编程的数学原理 – 博客频道 – CSDN.NET

 

PHP函数serialize()与unserialize()说明及案例。想要将已序列化的字符串变回 PHP 的值,可使用unserialize()。serialize()可处理除了resource之外的任何类型。甚至可以serialize()那些包含了指向其自身引用的数组。你正serialize()的数组/对象中的引用也将被存储。

 

serialize()返回字符串,此字符串包含了表示value的字节流,可以存储于任何地方。这有利于存储或传递 PHP 的值,同时不丢失其类型和结构。

想要将已序列化的字符串变回 PHP 的值,可使用unserialize()。serialize()可处理除了resource之外的任何类型。甚至可以serialize()那些包含了指向其自身引用的数组。你正serialize()的数组/对象中的引用也将被存储。

当序列化对象时,PHP 将试图在序列动作之前调用该对象的成员函数__sleep()。这样就允许对象在被序列化之前做任何清除操作。类似的,当使用unserialize()恢复对象时, 将调用__wakeup()成员函数。

注:在 PHP 3 中,对象属性将被序列化,但是方法则会丢失。PHP 4 打破了此限制,可以同时存储属性和方法。请参见类与对象中的序列化对象部分获取更多信息。

serialize()和unserialize()在php手册上的解释是:

serialize — Generates a storable representation of a value

serialize — 产生一个可存储的值的表示

unserialize — Creates a PHP value from a stored representation

unserialize — 从已存储的表示中创建 PHP 的值

serialize,翻译过来叫“连载, 使连续”,通常称它为“序列化

这个函数很好用,特别是和unserialize一起配合使用

我觉得比较有用的地方就是将数据存入数据库或记录在文件中的时候

当然这种数据必须是比较复杂的(不复杂也不需要serialize了,我觉得起码得是一个一数组),而且是数据库中的非“索引或主键”,当然最好这个数据库字段在系统中和任何搜索程序无关,当然serialize后的数据其实还是能够搜索的,因为具体的数据并没有被加密或改变

<?php
//简单一点的
$array = array();
$array[‘key’] = ‘website’;
$array[‘value’]=’www.isoji.org’;
$a = serialize($array);
echo $a;
unset($array);
$a = unserialize($a);
print_r($a);
//声明一个类
class dog {

var $name;
var $age;
var $owner;

function dog($in_name=”unnamed”,$in_age=”0″,$in_owner=”unknown”) {
$this->name = $in_name;
$this->age = $in_age;
$this->owner = $in_owner;
}

function getage() {
return ($this->age * 365);
}

function getowner() {
return ($this->owner);
}

function getname() {
return ($this->name);
}
}
//实例化这个类
$ourfirstdog = new dog(“Rover”,12,”Lisa and Graham”);
//用serialize 函数将这个实例转化为一个序列化的字符串
$dogdisc = serialize($ourfirstdog);
print $dogdisc; //$ourfirstdog 已经序列化为字符串 O:3:”dog”:3:{s:4:”name”;s:5:”Rover”;s:3:”age”;i:12;s:5:”owner”;s:15:”Lisa and Graham”;}

print ‘<BR>’;

/*
—————————————————————————————–
在这里你可以将字符串 $dogdisc 存储到任何地方如 session,cookie,数据库,php文件
—————————————————————————————–
*/

//我们在此注销这个类
unset($ourfirstdog);

/* 还原操作 */

/*
—————————————————————————————–
在这里将字符串 $dogdisc 从你存储的地方读出来如 session,cookie,数据库,php文件
—————————————————————————————–
*/
//我们在这里用 unserialize() 还原已经序列化的对象
$pet = unserialize($dogdisc); //此时的 $pet 已经是前面的 $ourfirstdog 对象了
//获得年龄和名字属性
$old = $pet->getage();
$name = $pet->getname();
//这个类此时无需实例化可以继续使用,而且属性和值都是保持在序列化之前的状态
print “Our first dog is called $name and is $old days old<br>”;
print ‘<BR>’;
?>

Android-webview和js互相调用 - Fwl的小花园 - 博客园

mikel阅读(1289)

来源: Android-webview和js互相调用 – Fwl的小花园 – 博客园

Android 和 H5 都是移动开发应用的非常广泛。市面上很多App都是使用Android开发的,但使用Android来开发一些比较复杂附属类,提示性的页面是得不偿失的。而H5具有开发速度快,更新不用依赖于App的更新,只需要服务端更新相应的页面即可,所以,App和H5页面相结合就显得尤为重要。而android和H5都不可能每次都是独立存在的,而是相互影响也相互的调用,获取信息等,例如,H5页面要获取App中的用户的基本信息,或者App端要操作H5页面等,下面来看看这两是怎么交互的。

先来看一下项目的整体架构(Android studio中的项目)

整个项目的结构就是这样的,里面最主要的就是assets下面的js_webView.html文件和代码中的WebViewJsActivity,其中项目里面的MainActivity只是做了个跳转而已,跳转到WebViewJsActivity。就这样。

下面上代码:(js_webView.html)

html里面的代码也比较简单,整个html中就一个Button,点击这个Button的时候去执行JavaScript中的 jsCallAndroid() 方法。

网页中有关 JavaScript 的代码也比较简单,整个 js 就2个方法,一个是 jsCallAndroid() ,一个是 androidCallJs() 。看方法名就知道了,分别是 js 调用 Android 的和 Android 调用 js 的。

先不要去管 jsCallAndroid() 里面做的是什么,待会会解释,来看看 androidCallJs() 这个方法里面做的就是弹出一个信息提示框,具体提示什么信息都不重要了,随便。

再来看看代码部分(WebViewActivity的布局文件): 

整个布局文件也很简单,一个按钮和一个WebView,按钮是用来测试 Android 调用 js 用的,js 调用 Android 就当然是 webview 加载的网页里面的按钮了。

再来看看 Java 代码部分(WebViewActivity):

下面来看看代码部分:

37-42行:这几行就是android中的按钮的点击事件,没什么好解释的,来看看点击事件做的是什么?点击事件做的是:调用 webview 的 loadurl 方法去调用 js 中的方法;调用的方式是:前面是 JavaScript 中间用 : 分隔 最后是 要调用的 js 的方法名。

45-55行:这几行就是有关于 Webview 的设置等,46-51 这几行是指支持弹窗,也就是支持 html 网页弹框,因为前面的 html 代码中,有我们 Android 调用 js 的时候,调用成功就 js 弹窗,所以这里要加上这个设置。接下来是53行,53行指的是支持 javascript 这里指的是支持 html 中的 javascript 解析,不管是不是 js 和 Android 交互,只要网页中含有 js ,都要。最关键的就是54行,54行就是 javascript 和 Android 交互的了,addJavascriptInterface 方法需要接受两个参数,第一个是与之相对应的 js 调用 Android 本地的类的对象,这个例子中的就是58-63行这个类的对象,第二个参数就是和前面网页中的js代码中的 jsCallAndroid 方法中的 wv.sayHello(),这里的 wv 就和这个参数(wv)与之相对应,而 sayHello() 就是对应的第一个参数的对象里面的方法。

最后是58-63行,这几行没什么好解释的了,只是如果调用成功就打印一行日志。仅此检验是否调用成功而已。

整个 demo 代码到此完毕,好激动,赶紧运行试试看。

 

运行的结果会让很多人失望,只是android调用js成功了,但 js 调用 android 不成功。

 

这是为什么呢?这里要涉及到的是有关于 webview 和 js 的安全性的问题。js 可以通过这种方式下载恶意代码在 android 上执行,具体有兴趣的可以去 Google 一下,所以上面这种写法只是对于 Api16以前的android手机是适用的,16以后,谷歌对这个安全性问题进行了修复。将其注解到android自带的一个javascriptInterfface类中。下面就来看看16以后的写法是咋样的?

有了注解,简直如虎添翼,非常方便。还是原来的配方,还是原来的味道,原汁原味。除了 Activity 中的代码需要修改,其他都不动。

改动的代码有55行,直接传一个 this(Context) 对象就可以了,那么,原来的 JsInterface 就可以不要了。不要那我 sayHello 方法写到哪里呢?既然你传递的是 this ,当然是写到 this 里面咯(59-62行)。不同的是,这个 sayHello() 方法必须加上一个 JavascriptInterface 的注解。

 

OK了,16以前和16以后的都有了,不就OK了么。在添加javascript的时候判断一下 Api 版本就可以了,哈哈。。。

 

不不不,肯定不是这样子做。指需要在onCreate() 方法上添加 @SuppressLint(“JavascriptInterface”) 注解即可。

看下面的就是终极代码了。

对,没错,就是这样子。大功告成。

最后需要提一点的是,上面的例子是可以执行,正常情况下都没什么问题,但你看看网上的demo,很多在 android 调用 js 的时候是开一个子线程去调用,没错,实际开发中,是必须要这样子做的。好处就不言而喻了。这一点看最后一张代码图,这里也有给出,直接调用webview的post,里面就是 Android 调用 js 了。

 

这篇博文到此结束。

2016-10-20

AngularJs项目实践总结 - pilixiami - 博客园

mikel阅读(964)

来源: AngularJs项目实践总结 – pilixiami – 博客园

    今年3月接触AngularJs,并且在6月的项目中开始应用,从踩坑到填坑花了不少时间,根据项目中的实际应用情况总结了一些经验,如下:

一.UI控件选择

Angularjs是不缺控件的,Github里现成的控件非常丰富,基本上足以应付一个普通管理系统中常见的控件需求。但是控件的丰富会带来选择的困难。选择控件要满足几个原则:
原则1:符合业务场景
原则2:控件持续更新
原则3:满足性能要求

举几个例子。首先是上传附件的控件。项目中要用到附件上传,谷歌上搜到了三个控件,分别是
https://github.com/leon/angular-upload
https://github.com/danialfarid/ng-file-upload
https://github.com/nervgh/angular-file-upload

因为项目需要兼容IE9,就重点关注了这三个控件对浏览器的兼容性。第一个控件没有任何说明,第二个控件支持IE9,但是前提是要安装flash,第三个控件支持IE8和9,但是只支持部分功能。从浏览器兼容性的角度考虑,最终选择了控件三。

再举一个例子,下拉框控件。html原生的select功能比较单一,并且option的样式很难修改,在前端各个框架所用的下拉框基本上都是重新实现的。Angularjs也不例外。项目中刚开始选用了ui-select2。后来在ui-select2的介绍中看到这句话:
This directive is now obsolete. A new initiative, more active, and 100% angular is available at https://github.com/angular-ui/ui-select.
发现ui-select2已经有3年没有更新了,果断弃坑选用ui-select。

最后谈谈原则3,还是说ui-select吧,它虽然是ui-select2的改进版,但是性能上是存在问题的,根据stackoverflow上的问答,一个ui-select里包含过多选择项或者一个页面包含过多ui-select控件时,性能有明显降低。因为这一点,曾考虑用其他控件替换掉ui-select,不过项目中并不存在大数据量和过多控件的情况,最后仍然保留了它。在满足原则1和2和前提下,只能尽量满足原则3。

一个新项目在开发前,最好能根据需求调研可能用到的UI控件,并尝试写一些demo,尤其对复杂的UI控件。比如ui-grid,有太多的指令和api,花费在阅读文档和官方实例代码的时间也是一笔不小的投入。

二.自定义指令

自定义的指令要加命名空间(前缀),防止全局指令名污染,就像JavaScript中防止全局变量污染一样。在项目中,某个页面出现了这样的错误:
Error: [$compile:multidir] Multiple directives [refresh, uiSelectChoices] asking for template on: <ui-select-choices repeat=”searchRes in searchRes” refresh=”searchMedia($select)”>

但是新建一个测试用的解决方案,ui-select却是正常的。几经搜索,后来才发现在项目公共的directive里定义了一个叫refresh的指令,它和ui-select的refresh指令重名了。
解决办法很简单,重命名自定义的refresh指令。

三.页面防抖动

在页面初始化的时候,用户可能会先看到 {{ }},然后闪烁一下才出现真正的内容。这是因为Angularjs会在dom加载完后才会解析{{ }}中的内容,在这之前,{{ }}不是Angularjs的插值表达式,而是文本。
解决办法:
1. 在要显示的内容上使用 ng-cloak指令,并且添加如下样式

复制代码
<style>
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak 
{
   display: none !important;
}
</style>
复制代码

2. 使用 ng-bind 替代 {{ }}

四.模块化思维

Angularjs推荐模块化开发,module的本意即是模块化,但是在Angularjs 1.X中,module更多体现出来的是一个“命名空间”的概念,而不是真正意义上的模块化。比如A模块依赖B模块,B模块应该是一个独立的东西,但是被A引用之后,A、B模块中的指令,服务,控制器全部混在了一起,使用指令、控制器时甚至不需要指定是哪个模块中的指令和控制器。在Angularjs2中已经抛弃了module,ES6也引入了JavaScript底层的模块化。在模块化这方面,不必按照Angularjs 1.X铺好的路走。

在项目中,我们的做法是,整个单页面应用是一个module,每个页面对应一个controller和view,公共的功能写在service中(这点还需要改进,呵呵)。
controller的定位应该是一个完整且尽可能小的功能模块。比如一个列表页,点击某条记录后弹窗显示该记录的详细信息,那么列表页写一个controller,详细页写另一个controller。controller之间是低耦合的,如果有一定的依赖关系,使用事件广播与接收进行通讯($emit, $broadcast, $on)。controller是不可复用的。
公共的逻辑写在service中,并且按功能分类,满足单一职责。使用时用依赖注入。避免写成全局的公共方法。

五.懒加载

单页面应用如果体量较小,完全不需要懒加载,把所有脚本打包压缩在一起是更好的解决方案。但是体量较大,加载的脚本又多又大,就需要考虑懒加载的方式了。按需加载文件,而不是一次性加载整个应用所需要的全部文件。懒加载的方式推荐用ocLazyLoad,而不要用requireJs。因为requireJs只能加载文件,无法注册module,controller,directive,而ocLazyLoad不但可以加载文件,也可以完成注册。配合ui-route的路由管理,实现懒加载非常方便。

六.性能

Angularjs采用脏检测的方式来检查对象的变化,与其他框架相比——比如同为MVVM模式的vue.js或者使用了虚拟dom的React——Angularjs的性能并不出众。但是,开发一个单页面应用或者一个管理系统,性能完全不是瓶颈。造成Angularjs性能降低的关键因素往往是添加了太多的watcher,超过2000(经验数值)个watcher时,会明显降低性能。所以提高性能的基本方法就是尽量减少watcher数量,比如使用ng-repeat时限制数组的长度并使用track by,以及一次性数据绑定{{::x}}

七.安全

AngularJs本身不允许不安全的代码,比如controller中定义一段带有html标签的字符串:
$scope.html=”<p>text</p>”;
在页面上显示的是原始的字符串,而不是一个段落。这是Angularjs自身的防XSS攻击机制。除此另外,作为开发人员,应该注意不要在模版中动态签入用户输入的数据。当然,如果需要显示html编码后的内容,也是可以的,使用$sanitize或$sce服务即可。$sanitize会按照Angularjs自身设置的白名单来净化html,$sce服务包含有$sce.trustAs,$sce.trustAsHtml,$sce.trustAsUrl,$sce.trustAsResourceUrl,$sce.trustAsJs等方法,用于编码可信任的html标签。

总结:Angularjs作为当前流行的MVVM框架,开发管理类的CRUD系统真的太合适了。JavaScript中一切皆对象,而在Angularjs中可以说一切皆数据,以数据驱动的方式解决dom的更新,提升不少开发效率。本次项目只是Angularjs的首次应用,只接触到了框架本身的部分功能,希望以后能有更多项目应用Angularjs。另外,Angularjs2已经在9月15日正式发布了,也许某天可以用Angularjs2来开发新的项目~

Android性能优化之巧用软引用与弱引用优化内存使用 - 总李写代码 - 博客园

mikel阅读(1219)

来源: Android性能优化之巧用软引用与弱引用优化内存使用 – 总李写代码 – 博客园

前言:

从事Android开发的同学都知道移动设备的内存使用是非常敏感的话题,今天我们来看下如何使用软引用与弱引用来优化内存使用。下面来理解几个概念。

1.StrongReference(强引用)

强引用是我们最最常见的一种,一般我们在代码中直接通过new出来的对象等,都是强引用,强引用只要存在没有被销毁,内存就不会被系统回收。我们以生成Bitmap为例如下:

Bitmap imageBitmap = readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5);

生成Bitmap代码:

    public Bitmap readBitmapFromResource(Resources resources, int resourcesId) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        return BitmapFactory.decodeResource(resources, resourcesId, options);
    }

2.SoftReference(软引用)

软引用是用来描述一些有用但并不是必需的对象,在内存严重不足的情况下会被系统回收,如果该对象可能会经常使用的,就尽量用软引用。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。这里还是以缓存Bitmap为例:

 SoftReference<Bitmap> softReference = new SoftReference<Bitmap>(readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5));
 Bitmap bitmap = softReference.get();

3.WeakReference(弱引用)

弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象,WeakReference 的强度又明显低于 SoftReference,所以如果该对象不被使用的可能性更大些,就可以用弱引用。还是以缓存Bitmap为例:

 WeakReference<Bitmap> weakReference = new WeakReference<Bitmap>(readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5));
 Bitmap bitmap1 = weakReference.get();

4.PhantomReference(虚引用)

虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。还是以缓存Bitmap为例:

 ReferenceQueue<Bitmap> queue = new ReferenceQueue<Bitmap>();
 PhantomReference<Bitmap>  phantomReference = new PhantomReference<Bitmap>(readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5),queue);
 Bitmap bitmap2 = phantomReference.get();

5.几种引用被回收概念测试

从上面的分析可以看出内存被系统回收的概率从小到大是:虚引用–弱引用–软引用–强引用,我们写个程序来验证一下。

复制代码
public class MainActivity extends AppCompatActivity {
    private LinearLayout request_layout;
    private PhantomReference<Bitmap> phantomReference;
    private WeakReference<Bitmap> weakReference;
    private SoftReference<Bitmap> softReference;
    private Bitmap strongReference;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        request_layout = (LinearLayout) findViewById(R.id.request_layout);

        findViewById(R.id.request_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                testReference();
            }
        });
    }

    private void testReference() {
        //模拟内存使用 往一个布局中不断加入ImageView来模拟内存使用
        ImageView imageView = new ImageView(this);
        Bitmap imageBitmap = readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5);
        imageView.setImageBitmap(imageBitmap);
        request_layout.addView(imageView);

        if (strongReference == null) {
            strongReference = readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5);
        }
        Log.e("Reference", "StrongReference---->" + strongReference);
        if (softReference == null) {
            softReference = new SoftReference<Bitmap>(readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5));
        }
        Bitmap bitmap = softReference.get();
        Log.e("Reference", "SoftReference---->" + bitmap);

        if (weakReference == null) {
            weakReference = new WeakReference<Bitmap>(readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5));
        }
        Bitmap bitmap1 = weakReference.get();
        Log.e("Reference", "WeakReference---->" + bitmap1);

        if (phantomReference == null) {
            ReferenceQueue<Bitmap> queue = new ReferenceQueue<Bitmap>();
            phantomReference = new PhantomReference<Bitmap>(readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5), queue);
        }
        Bitmap bitmap2 = phantomReference.get();
        Log.e("Reference", "PhantomReference---->" + bitmap2);
    }

    public Bitmap readBitmapFromResource(Resources resources, int resourcesId) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        return BitmapFactory.decodeResource(resources, resourcesId, options);
    }

}
复制代码

第一次点击打印信息:

通过打印信息可以虚引用直接回收掉了,或者可以说直接不存在引用。

接下来多次点击打印信息:

在模拟内存使用越来越紧张的情况下,并没有出现先回收弱引用,再回收软引用,而是两个一并回收掉了,其实按照Java正常引用顺序是软引用强于弱引用,但是从 Android 2.3 (API Level 9)开始,垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用像弱引用一样变得不再可靠。所以图片缓存不再使用软引用而采用LRU算法。但是强引用一直毅力不倒。

 总结:

从上面的介绍及测试对比可以得知,如果我们比较在意APP的性能的话,我们可以把哪些不常用并且占用内存比较大的对象用软引用或者弱引用来做缓存处理,鉴于保险起见,可以酌情选择使用弱引用还是软引用,实测下来二者被回收的概率相差无几。

干我们这行,啥时候懈怠,就意味着长进的停止,长进的停止就意味着被淘汰,只能往前冲,直到凤凰涅槃的一天!

[译]15个关于Chrome的开发必备小技巧 - 猴子猿 - 博客园

mikel阅读(950)

来源: [译]15个关于Chrome的开发必备小技巧 – 猴子猿 – 博客园

谷歌Chrome,是当前最流行且被众多web开发人员使用的浏览器。最快六周就更新发布一次以及伴随着它不断强大的开发组件,使得Chrome成为你必备的开发工具。例如,在线编辑CSS,console以及Debugger这些常用的调试技术,或许你已经了解。在本篇文章中,我们将介绍15个炫酷且实用的技巧,这将更快的提高你的开发效率。

一、快速查找文件

如果你使用过Sublime,那么你会知道’Go to anything’的强大。没错,Chrome现在也有了这一功能。

操作如下:

1、F12打开你的Chrome调试器;

2、按下Ctrl+P(Mac上Cmd + P);

3、搜索你想打开的文件名即可。

二、在源代码中搜索

但是,如果我们想在整个工程下,查找一段源代码呢?

操作如下:

1、F12打开你的Chrome调试器;

2、按下Ctrl+Shift+F(Mac上Cmd+Opt+F);

3、在输入框中输入你想查询的源代码,回车,就OK啦。

注:该搜索也支持正则表达式。

三、跳到指定行

当你在Chrome调试器的sources栏,已经打开了文件,Chrome也允许你跳到指定的行数,在Windows和Linux系统下,只需按下Ctrl+G(Mac上Cmd+L),然后输入你指定的行数即可。

另一种,方法就是Ctrl+O,输入”:”+行数即可。

四、在控制台(Console)中获取DOM元素

Chrome控制台,提供了方法和变量来快速获取页面中的DOM元素,如下:

1、$()—就是document.querySelector()原生方法的映射。功能嘛,就是获取并返回第一个与填写的CSS属性匹配的DOM元素,如$(‘div’)就会返回第一个出现在页面中的div元素。

2、$$()—就是document.querySelectorAll()原生方法的映射。功能嘛,就是获取并返回一个数组,数组中包含了所有与你填写的CSS属性匹配的DOM元素。

3、$0–$4—代表你在Chrome调试器中操作不同DOM元素的历史记录,且最多记录5次,故而只有$0-$4这五个变量。$0代表最近一次,依次类推。

五、多光标

另一个牛逼的功能就是多光标。

当你想在呈现的文件中多处操作代码时,你可以通过按住Ctrl(Mac上Cmd),然后鼠标点击,你想要出现的光标处即可。

六、保存日志

在console面板上勾选‘保存日志’选项,则不会在你每次加载页面时,清空日志。当你想要调查页面关闭前的bugs时,可要记住这一选项哦。

七、格式化代码

Chrome通过其内置的优化器,帮助你提高文件内容的可读性。对于压缩过或者杂乱的代码,尤为适用。

怎么实现呢?

操作如下:

1、F12打开Chrome开发工具;

2、选择你想要阅读的文件;

3、点击文件下方的”{ }”状按钮即可。

九、设备模拟器

另一个十分酷炫的功能就是,模拟移动设备端。

例如我们可以通过Chrome模拟人为触摸屏幕和晃动设备。你甚至可以通过它改变你的地理位置哦。

操作如下:

1、F12打开Chrome调试器;
2、在调试器底部选中Emulation选项;

3、最后在Emulation面板中,左侧选中Sensors即可。

十、颜色选择器

当你调用了Chrome的颜色选择器后,你可以通过你的鼠标,悬浮在网页中的任意处,获取颜色,它会十分精准地将其转换成对应的编码格式。

是不是很炫酷?

操作如下:

1、F12打开Chrome调试器;

2、选中目标元素;

3、在样式编辑器中,点击颜色预览,就会出现这个颜色选择器。

十一、强制改变元素状态

Chrome开发工具有一个强制改变元素CSS状态的功能,如:hover和:focus。对于CSSer比较方便。

十二、可视化“隐藏的DOM”

Web浏览器在构建例如textbox,button以及input这些元素时,通常会隐藏在其之下的展现层元素。

但是,我们可以通过Setting à General,在General面板中选中’Show user agent shadow DOM’这一选项,来展示这些被隐藏掉的基础元素。

你甚至可以单独地去设置它们的样式。

十三、选中下一个匹配项

当你选中一个匹配项后,利用Ctrl+D(Mac上Cmd+D),就会将下一个相同的匹配项也选中,该功能可以帮助你同时编辑它们。

十四、 改变颜色格式

在颜色预览中,通过Shift + 鼠标点击,就可以在rgba,hsl和hexadecimal三种格式中,来回切换。

十五、利用Chrome的工作空间,编辑本地文件

Chrome的工作空间,也是非常强大的,它可以直接编辑和保存你的本地文件,无需额外的操作,例如复制、粘贴。怎么配置它呢?

操作如下:

1、 F12打开Chrome调试器

2、 找到Sources栏,出现在左侧的控制面板,点击鼠标右键,选择Add Folder To Workspace。或者,直接将你整个工程文件夹,拖拽到调试器中。

这样操作后,不管你打开哪个页面,都会出现刚才你操作的文件。为了更加有用,你可以将页面中用到的文件映射到相应的文件夹,允许在线编辑和简单的保存。

 

原文:15 Must-Know Chrome DevTools Tips and Tricks

CentOS 6.5系统上安装SVN服务器 - cooldream2009 - 博客园

mikel阅读(918)

来源: CentOS 6.5系统上安装SVN服务器 – cooldream2009 – 博客园

有效地管理源代码的方式是使用工具去帮助我们管理 , SVN(Subversion)就是目前主流的源代码管理工具 , 也称为版本控制工具。

本文主要介绍CentOS6.5上安装SVN服务器,配置SVN服务器的数据仓库,SVN服务的启动查看和停止,SVN服务的开机自启动,安装SVN客户端等内容。

 

安装SVN

 

1 检查系统是否自带SVN

svnserve –version

如果没有安装,系统会提示svnserve是个无效的命令。

2 安装SVN

yum –y install subversion

3 检查安装是否成功

svnserve –version

返回值:

svnserve, version 1.6.11 (r934486)

compiled Aug 17 2015, 08:37:43

Copyright (C) 2000-2009 CollabNet.

Subversion is open source software, see http://subversion.tigris.org/

This product includes software developed by CollabNet (http://www.Collab.Net/).

The following repository back-end (FS) modules are available:

* fs_base : Module for working with a Berkeley DB repository.

* fs_fs : Module for working with a plain file (FSFS) repository.

Cyrus SASL authentication is available.

 

创建SVN数据仓库

 

1创建数据仓库

首先创建一个文件夹

mkdir -p /opt/svn/repositories

将创建的文件夹设置为数据仓库

svnadmin create /opt/svn/repositories

执行上面的命令后,自动建立repositories库,查看/opt/svn/repositories 文件夹发现包含了conf,db,format,hooks,locks, README.txt等文件,说明一个SVN库建立完成。

 

2 配置数据仓库

进入上面生成的文件夹conf下,进行配置

cd /opt/svn/repositories/conf

 

配置用户名和密码passwd

vi passwd

passwd文件的内容如下:

### This file is an example password file for svnserve.

### Its format is similar to that of svnserve.conf. As shown in the

### example below it contains one section labelled [users].

### The name and password for each user follow, one account per line.

[users]

# harry = harryssecret

# sally = sallyssecret

test = 123456 ##新增用户的用户名和密码

 

配置权限控制authz

vi authz

目的是设置哪些用户可以访问哪些目录,authz文件的内容如下:

### This file is an example authorization file for svnserve.

### Its format is identical to that of mod_authz_svn authorization

### files.

### As shown below each section defines authorizations for the path and

### (optional) repository specified by the section name.

### The authorizations follow. An authorization line can refer to:

###  – a single user,

###  – a group of users defined in a special [groups] section,

###  – an alias defined in a special [aliases] section,

###  – all authenticated users, using the ‘$authenticated’ token,

###  – only anonymous users, using the ‘$anonymous’ token,

###  – anyone, using the ‘*’ wildcard.

###

### A match can be inverted by prefixing the rule with ‘~’. Rules can

### grant read (‘r’) access, read-write (‘rw’) access, or no access

### (”).

[aliases]

# joe = /C=XZ/ST=Dessert/L=Snake City/O=Snake Oil, Ltd./OU=Research Institute/CN=Joe Average

[groups]

# harry_and_sally = harry,sally

# harry_sally_and_joe = harry,sally,&joe

# [/foo/bar]

# harry = rw

# &joe = r

# * =

# [repository:/baz/fuz]

# @harry_and_sally = rw

# * = r

[/]

test = rw

设置[/]代表根目录下所有的资源

 

配置服务svnserve.conf

vi svnserve.conf

svnserve.conf文件的内容如下:

[general]

#匿名访问的权限,可以是read,write,none,默认为read

anon-access=none

#使授权用户有写权限

auth-access=write

#密码数据库的路径

password-db=passwd

#访问控制文件

authz-db=authz

#认证命名空间,subversion会在认证提示里显示,并且作为凭证缓存的关键字

realm=/opt/svn/repositories

 

三 SVN服务的启动、查看及停止

 

1 启动svn服务

svnserve -d -r /opt/svn/repositories

 

2 查看SVN监听的端口

netstat -anp |grep svn

返回:

tcp  0  0 0.0.0.0:3690  0.0.0.0:*  LISTEN  2085/svnserve

 

3 停止启动SVN

killall svnserve    #停止

 

设置SVN的开机自启动

 

1 创建svn.sh文件

在/root文件夹下,创建svn.sh文件

cd /root

vi svn.sh

编辑svn.sh文件,加入以下内容

#!/bin/bash

svnserve –d –r /opt/svn/repositories

保存退出

 

2.添加可执行权限
命令行运行#chmod ug+x /root/svn.sh
3.添加自动运行
打开(vi或gedit)/etc /rc.local,在最后添加一行内容如下:/root/svn.sh保存退出。
4.检查
重启服务器,使用ps-ef看看svn进程是否启动了。以后开机就自动启动svn了。

 

安装SVN客户端

以业界流行的TortoiseSVN为例,下载地址:

http://sourceforge.net/projects/tortoisesvn/files/latest/download?source=dlp

客户端连接地址:svn://公网或内网的IP地址(如192.168.0.141):3690

用户名/密码: test/123456  ##要和之前设置的用户名和密码匹配。