存档在 2016年5月

15 个 Android 通用流行框架大全

2016年5月30日

1. 缓存

2.图片加载

3. 图片处理

4. 网络请求

  • Android Async HTTP  Android异步HTTP库
  • AndroidAsync    异步Socket,HTTP(客户端+服务器),WebSocket,和socket.io库。基于NIO而不是线程。
  • OkHttp  一个Http与Http/2的客户端
  • Retrofit    类型安全的Http客户端
  • Volley  Google推出的Android异步网络请求框架和图片加载框架

5. 网络解析

  • Gson    一个Java序列化/反序列化库,可以将JSON和java对象互相转换
  • Jackson Jackson可以轻松地将Java对象转换成json对象和xml文档,同样也可以将json、xml转换成Java对象
  • Fastjson    Java上一个快速的JSON解析器/生成器
  • HtmlPaser   一种用来解析单个独立html或嵌套html的方式
  • Jsoup   一个以最好的DOM,CSS和jQuery解析html的库

6. 数据库

  • OrmLite JDBC和Android的轻量级ORM java包
  • Sugar   用超级简单的方法处理Android数据库
  • GreenDAO    一种轻快地将对象映射到SQLite数据库的ORM解决方案
  • ActiveAndroid   以活动记录方式为Android SQLite提供持久化
  • SQLBrite    SQLiteOpenHelper 和ContentResolver的轻量级包装
  • Realm   移动数据库:一个SQLite和ORM的替换品

7. 依赖注入

8. 图表

9. 后台处理

  • Tape    一个轻快的,事务性的,基于文件的FIFO的库
  • Android Priority Job Queue  一个专门为Android轻松调度任务的工作队列

10. 事件总线

  • EventBus    安卓优化的事件总线,简化了活动、片段、线程、服务等的通信
  • Otto    一个基于Guava的增强的事件总线

11. 响应式编程

  • RxJava  JVM上的响应式扩展
  • RxJavaJoins 为RxJava提供Joins操作
  • RxAndroid   Android上的响应式扩展,在RxJava基础上添加了Android线程调度
  • RxBinding   提供用RxJava绑定Android UI的API
  • Agera   Android上的响应式编程

12. Log框架

  • Logger  简单,漂亮,强大的Android日志工具
  • Hugo    在调试版本上注解的触发方法进行日志记录
  • Timber  一个小的,可扩展的日志工具

13. 测试框架

Android自带很多测试工具:JUnit,Monkeyrunner,UiAutomator,Espresso等

14. 调试框架

  • Stetho  调试Android应用的桥梁,使得可以利用Chrome开发者工具进行调试

15. 性能优化

  • LeakCanary  内存泄漏检测工具
  • ACRA  Android应用程序崩溃报告

android ndk multiple target patterns解决办法

2016年5月26日

出现问题:/Users/macmini/Documents/ME/Project/CODE/SerialAPI/obj/local/mips/objs/serialport/SerialPort.o.d:1: *** multiple target patterns. Stop.

解决办法:
删除Obj目录下以前生成的文件,重新ndk-build即可

[mips] Compile        : serialport <= SerialPort.c
[mips] SharedLibrary  : libserialport.so
[mips] Install        : libserialport.so => libs/mips/libserialport.so

php serialize()与unserialize()的用法

2016年5月20日

serialize()和unserialize()在php手册上的解释是:
serialize — Generates a storable representation of a value
serialize — 产生一个可存储的值的表示
unserialize — Creates a PHP value from a stored representation
unserialize — 从已存储的表示中创建 PHP 的值

<?php
//声明一个类
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>';
?>

其实serialize()就是将PHP中的变量如对象(object),数组(array)等等的值序列化为字符串后存储起来.序列化的字符串我们可以存储在其他地方如数据库、Session、Cookie等,序列化的操作并不会丢失这些值的类型和结构。这样这些变量的数据就可以在PHP页面、甚至是不同PHP程序间传递了。而unserialize()就是把序列化的字符串转换回PHP的值。
当序列化对象时,PHP 将试图在序列动作之前调用该对象的成员函数 __sleep()。这样就允许对象在被序列化之前做任何清除操作。类似的,当使用 unserialize() 恢复对象时, 将调用 __wakeup() 成员函数unserialize() 对单一的已序列化的变量进行操作,将其转换回 PHP 的值。返回的是转换之后的值,可为 integer、float、string、array 或 object。如果传递的字符串不可解序列化,则返回 FALSE。

ARM Linux调试时的超时问题

2016年5月17日

最近遇到两个问题。第一是中兴arm9板,我在使用ssh登录的时候,会等待超过15秒时间,按理说开发主机与arm Linux位于同一个路由器子网下,应该很快连接的;第二个问题也是arm linux的问题,项目上使用ftp传输文件,但是ftp到arm Linux时会等待超过30秒时间,甚至超时。

原因:使用top指令发现并不是板子cpu和memory引起,排查后发现是DNS引起,我在想可能是主机和arm交互的时候,在寻找主机时,是向dns服务器请求转换,但是dns又没有响应引起的,所以,删除或者注释掉本地域名解析文件里设置的域名服务器就行了。
IMG_2320

IMG_2327

crontab编辑

2016年5月17日

使用

crontab -e

第一次会让你选择编辑器,如果选错的话还可以使用以下命令重新选择。

select-editor 

[sheel]Select an editor. To change later, run ‘select-editor’.
1. /bin/ed
2. /bin/nano <---- easiest 3. /usr/bin/vim.basic 4. /usr/bin/vim.tiny [/shell] 追加如下语句测试

*/2 * * * * echo "i am crontab" >>  /mnt/log.txt

Linux使用crontab定时计划任务

2016年5月16日

需要定时访问一个固定的链接,实现积分的转换,刚好用到crontab命令。

crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond进程,crond进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。
Linux下的任务调度分为两类,系统任务调度和用户任务调度。
系统任务调度:系统周期性所要执行的工作,比如写缓存数据到硬盘、日志清理等。在/etc目录下有一个crontab文件,这个就是系统任务调度的配置文件。
/etc/crontab文件包括下面几行:

[root@localhost ~]# cat /etc/crontab 
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=""HOME=/
# run-parts
51 * * * * root run-parts /etc/cron.hourly
24 7 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly

前四行是用来配置crond任务运行的环境变量,第一行SHELL变量指定了系统要使用哪个shell,这里是bash,第二行PATH变量指定了系统执行命令的路径,第三行MAILTO变量指定了crond的任务执行信息将通过电子邮件发送给root用户,如果MAILTO变量的值为空,则表示不发送任务执行信息给用户,第四行的HOME变量指定了在执行命令或者脚本时使用的主目录。下面几行的意义:

crontab文件的含义:
用户所建立的crontab文件中,每一行都代表一项任务,每行的每个字段代表一项设置,它的格式共分为六个字段,前五段是时间设定段,第六段是要执行的命令段,格式如下:
minute hour day month week command
其中:
minute: 表示分钟,可以是从0到59之间的任何整数。
hour:表示小时,可以是从0到23之间的任何整数。
day:表示日期,可以是从1到31之间的任何整数。
month:表示月份,可以是从1到12之间的任何整数。
week:表示星期几,可以是从0到7之间的任何整数,这里的0或7代表星期日。
command:要执行的命令,可以是系统命令,也可以是自己编写的脚本文件。
QQ图片20160516141621
在以上各个字段中,还可以使用以下特殊字符:
星号(*):代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。
逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”
中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”
正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如*/10,如果用在minute字段,表示每十分钟执行一次。

举列子:
crontab文件的一些例子:

30 21 * * * /usr/local/etc/rc.d/lighttpd restart 

上面的例子表示每晚的21:30重启apache。

45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart 

上面的例子表示每月1、10、22日的4 : 45重启apache。

10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart 

上面的例子表示每周六、周日的1 : 10重启apache。

0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart 

上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。

0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart 

上面的例子表示每星期六的11 : 00 pm重启apache。

* */1 * * * /usr/local/etc/rc.d/lighttpd restart 

每一小时重启apache

* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart 

晚上11点到早上7点之间,每隔一小时重启apache

0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart 

每月的4号与每周一到周三的11点重启apache

0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart 

一月一号的4点重启apache

0 */2 * * * /usr/bin/curl http://unix8.net/

两小时访问一次

*/10 * * * * /usr/bin/curl http://unix8.net/

10分钟访问一次

如何添加:

crontab -e 

再添加上面的命令。

Ecshop的Mobile广告管理系统移植到pc端后台

2016年5月15日

1.拷贝mobille/admin下的ads.php,ad_position.php,重命名为ads_mobile.php,ad_position.php到admin目录下;
2.修改上两个文件内的所有链接ads.php,ad_position.php为ads_mobile.php,ad_position.php;
3.修改templates下的ad_position_info.htm,ad_position_list.htm,ads_info.htm,ads_js.htm,ads_list.htm,adsense.htm其中的所有ads.php,ad_position.php为ads_mobile.php,ad_position.php(记得先备份这几个文件);
4.在admin/includes/inc_menu.php里修改ads.php,ad_position.php为ads_mobile.php,ad_position.php;
5.在后台便可见了,上传的图片放在了data/afficheimg里面,但是mobile端商城还是显示的是mobile/data/afficheimg里的图片,因此接下来修改mobile端的程序。
6.修改mobile/index.php里的代码为

function get_wap_advlist( $position, $num )
{
		$arr = array( );
		$sql = "select ap.ad_width,ap.ad_height,ad.ad_id,ad.ad_name,ad.ad_code,ad.ad_link,ad.ad_id from ".$GLOBALS['ecs']->table( "ecsmart_ad_position" )." as ap left join ".$GLOBALS['ecs']->table( "ecsmart_ad" )." as ad on ad.position_id = ap.position_id where ap.position_name='".$position.( "' and UNIX_TIMESTAMP()>ad.start_time and UNIX_TIMESTAMP()<ad.end_time and ad.enabled=1 limit ".$num );
		$res = $GLOBALS['db']->getAll( $sql );
		foreach ( $res as $idx => $row )
		{
				$arr[$row['ad_id']]['name'] = $row['ad_name'];
				$arr[$row['ad_id']]['url'] = "affiche.php?ad_id=".$row['ad_id']."&uri=".$row['ad_link'];
				$arr[$row['ad_id']]['image'] = "../data/afficheimg/".$row['ad_code'];
				$arr[$row['ad_id']]['content'] = "<a href='".$arr[$row['ad_id']]['url']."' target='_blank'><img src='../data/afficheimg/".$row['ad_code']."' width='".$row['ad_width']."' height='".$row['ad_height']."' /></a>";
				$arr[$row['ad_id']]['ad_code'] = $row['ad_code'];
		}
		return $arr;
}

这样首页的幻灯片就显示data/afficheimg里的图片里,但是下面广告还是显示mobile/data/afficheimg里的图片
7.修改mobile/includes/lib_insert.php里的代码为,大约在295行

 switch ($row['media_type'])
        {
            case 0: // 图片广告
                $src = (strpos($row['ad_code'], 'http://') === false && strpos($row['ad_code'], 'https://') === false) ?
                        DATA_DIR . "/../../data"."/afficheimg/$row[ad_code]" : $row['ad_code'];
                $ads[] = "<a href='affiche.php?ad_id=$row[ad_id]&amp;uri=" .urlencode($row["ad_link"]). "'
                target='_blank'><img src='$src' width='" .$row['ad_width']. "' height='$row[ad_height]'
                border='0' /></a>";
                break;
            case 1: // Flash
                $src = (strpos($row['ad_code'], 'http://') === false && strpos($row['ad_code'], 'https://') === false) ?
                        DATA_DIR . "/../../data"."/afficheimg/$row[ad_code]" : $row['ad_code'];
                $ads[] = "<object classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" " .
                         "codebase=\"http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0\"  " .
                           "width='$row[ad_width]' height='$row[ad_height]'>
                           <param name='movie' value='$src'>
                           <param name='quality' value='high'>
                           <embed src='$src' quality='high'
                           pluginspage='http://www.macromedia.com/go/getflashplayer'
                           type='application/x-shockwave-flash' width='$row[ad_width]'
                           height='$row[ad_height]'></embed>
                         </object>";
                break;
            case 2: // CODE
                $ads[] = $row['ad_code'];
                break;
            case 3: // TEXT
                $ads[] = "<a href='affiche.php?ad_id=$row[ad_id]&amp;uri=" .urlencode($row["ad_link"]). "'
                target='_blank'>" .htmlspecialchars($row['ad_code']). '</a>';
                break;
        }

8.修改商品目录里图片的路径,文件为mobile/catalog.php

/*分类调用id广告*/
function get_advlist( $position, $num )
{
		$arr = array( );
		$sql = "select ap.ad_width,ap.ad_height,ad.ad_id,ad.ad_name,ad.ad_code,ad.ad_link,ad.ad_id from ".$GLOBALS['ecs']->table( "ecsmart_ad_position" )." as ap left join ".$GLOBALS['ecs']->table( "ecsmart_ad" )." as ad on ad.position_id = ap.position_id where ap.position_name='".$position.( "' and UNIX_TIMESTAMP()>ad.start_time and UNIX_TIMESTAMP()<ad.end_time and ad.enabled=1 limit ".$num );
		$res = $GLOBALS['db']->getAll( $sql );
		foreach ( $res as $idx => $row )
		{
				$arr[$row['ad_id']]['name'] = $row['ad_name'];
				$arr[$row['ad_id']]['url'] = "affiche.php?ad_id=".$row['ad_id']."&uri=".$row['ad_link'];
				$arr[$row['ad_id']]['image'] = "../data/afficheimg/".$row['ad_code'];
				$arr[$row['ad_id']]['content'] = "<a href='".$arr[$row['ad_id']]['url']."' target='_blank'><img src='../data/afficheimg/".$row['ad_code']."' width='".$row['ad_width']."' height='".$row['ad_height']."' /></a>";
				$arr[$row['ad_id']]['ad_code'] = $row['ad_code'];
		}
		return $arr;
}

阿里大鱼 短信使用

2016年5月14日

下载SDK,解压引入Autoload.php、TopSdk.php及aliyun和top两个文件夹。
我引入的位置是 APP_PATH/Common/Lib/Alidayu/,不动tp文件我觉得好些。
新建一个类文件 SendMSM.class.php,这个根据自己需求来。

<?php

namespace Lib\Alidayu;


include('TopSdk.php');
use TopClient; 
use AlibabaAliqinFcSmsNumSendRequest;

class SendMSM {
    
    public function send($recNum='', $smsParam='', $smsTemplateCode='SMS_8525079', $smsFreeSignName='短信测试'){
        $c = new TopClient;
        $c->format = "json";
        $c->appkey = C('AlidayuAppKey');
        $c->secretKey = C('AlidayuAppSecret');
        $req = new AlibabaAliqinFcSmsNumSendRequest;
        //$req->setExtend("123456");
        $req->setSmsType("normal");
        $req->setSmsFreeSignName($smsFreeSignName);
        $req->setSmsParam($smsParam);
        $req->setRecNum($recNum);
        $req->setSmsTemplateCode($smsTemplateCode);
        $resp = $c->execute($req);
        return $resp;
    }
    
}

我把AppKey 和 secret 放到了单独的配置文件,以便后期重置了可以在后台修改。

然后就是使用了,

<?php
namespace Admin\Controller;

use Think\Controller;
use Lib\Alidayu\SendMSM;

class IndexController extends Controller {
    public function index(){
        $this->sendMSM();
    }
    
    protected function sendMSM(){
        $alidayu = new SendMSM();
        $result = $alidayu->send('13000000000','{"code":"123456"}');
        dump($result);
    }
}

测试结果:

object(stdClass)[11]
  public 'result' => 
    object(stdClass)[12]
      public 'err_code' => string '0' (length=1)
      public 'model' => string '101550887105^1102084861016' (length=26)
      public 'success' => boolean true
  public 'request_id' => string '12cl9hupqvkgh' (length=13)