Title

Mysql 触发器相关


主要是触发Redis数据库更新,一般都有三种操作,对于数据表 AdminCustomerInfo

T_AdminCustomerInfo_AI -> AfterInsert

BEGIN
  DECLARE asId varchar(20);
  SET asId = CONCAT("C-",NEW.aiId);
  SET @ret= redis_command_v2("HSET","AccountInfoList",asId,
               json_object
               (
                   asId,
                   NEW.aiId AS aiId,
                   NEW.identityCardId AS identityCardId,
                   NEW.aInfoName AS aInfoName,
                   NEW.aInfoPicture AS aInfoPicture,
                   NEW.aInfoPhone AS aInfoPhone,
                   NEW.aInfoEmail AS aInfoEmail,
                   NEW.companyJoinState AS companyJoinState,
                   NEW.companyId AS companyId,
                   NEW.aInfoQQ AS aInfoQQ,
                   NEW.qqBind AS qqBind,
                   NEW.weChatBind AS weChatBind,
                   NEW.weiBoBind AS weiBoBind,
                   NEW.mailNotify AS mailNotify,
                   NEW.smsNotify AS smsNotify,
                   NEW.weChatNotify AS weChatNotify,
                   NEW.accountName AS accountName,
                   NEW.Password AS Password,
                   NEW.aInfoLevel AS aInfoLevel,
                   NEW.Balance AS Balance,
                   NEW.lastLogin AS lastLogin,
                   NEW.manId AS manId
               )
  );
  INSERT INTO App_RunInfo( asId )VALUES( asId );
END

T_AdminCustomerInfo_AU -> AfterUpdate

BEGIN
  DECLARE asId varchar(20);
  SET asId = CONCAT("C-",NEW.aiId);
  SET @ret= redis_command_v2("HSET","AccountInfoList",asId,
               json_object
               (
                   asId,
                   NEW.aiId AS aiId,
                   NEW.identityCardId AS identityCardId,
                   NEW.aInfoName AS aInfoName,
                   NEW.aInfoPicture AS aInfoPicture,
                   NEW.aInfoPhone AS aInfoPhone,
                   NEW.aInfoEmail AS aInfoEmail,
                   NEW.companyJoinState AS companyJoinState,
                   NEW.companyId AS companyId,
                   NEW.aInfoQQ AS aInfoQQ,
                   NEW.qqBind AS qqBind,
                   NEW.weChatBind AS weChatBind,
                   NEW.weiBoBind AS weiBoBind,
                   NEW.mailNotify AS mailNotify,
                   NEW.smsNotify AS smsNotify,
                   NEW.weChatNotify AS weChatNotify,
                   NEW.accountName AS accountName,
                   NEW.Password AS Password,
                   NEW.aInfoLevel AS aInfoLevel,
                   NEW.Balance AS Balance,
                   NEW.lastLogin AS lastLogin,
                   NEW.manId AS manId
               )
  );
END

T_AdminCustomerInfo_AD -> AfterDelete

BEGIN
  DECLARE asId varchar(20);
  SET asId = CONCAT("C-",OLD.aiId);
  SET @ret= redis_command_v2("HDEL","AccountInfoList",asId);
  DELETE FROM App_RunInfo WHERE asId = asId;
END

其它暂存

AccountTransaction => AccountTradePays 表同步

一. 同步插入交易记录

DELIMITER ||
    DROP TRIGGER IF EXISTS T_AfterInsert_ON_AccountTransaction ||
    CREATE TRIGGER T_AfterInsert_ON_AccountTransaction
    AFTER INSERT ON AccountTransaction
    FOR EACH ROW
    BEGIN
        INSERT INTO AccountTradePays( pSerial, asId, tradeMoney, tradeWay, tradeSource, tradeTitle, tradeContent, tradeState, cBalance )
        VALUES( NEW.tSerial, NEW.asId, NEW.tradeMoney, NEW.tradeWay, NEW.tradeSource, NEW.tradeTitle, NEW.tradeContent, NEW.tradeState, NEW.cBalance );
    END||
DELIMITER

DELIMITER &&
CREATE TRIGGER tri_memory_insert AFTER Insert ON T FOR EACH ROW
BEGIN
    insert into tempT(id,strName) VALUES(NEW.id,NEW.strName);
END &&
DELIMITER ;

二. 同步更新触发器

DELIMITER $$
    /*[DEFINER = { user | CURRENT_USER }]*/
    CREATE TRIGGER `a`.`触发器名` BEFORE UPDATE ON `a`.`table1`
    FOR EACH ROW BEGIN
        IF new.id != old.id THEN
            UPDATE `b`.`table2` SET `b`.`table2`.id=new.id WHERE `b`.`table2`.val=old.val;
        END IF;
    END$$
DELIMITER;

DELIMITER &&
    CREATE TRIGGER T_AfterUpdate_ON_AccountTransaction
    AFTER UPDATE ON AccountTransaction
    FOR EACH ROW
    BEGIN
        UPDATE AccountTradePays SET tradeState=NEW.tradeState WHERE pSerial = "AT-" + OLD.tId;
    END &&
DELIMITER ;

三. 同步删除触发器

DELIMITER ||
    DROP TRIGGER IF EXISTS T_AfterDelete_ON_AccountTransaction ||
    CREATE TRIGGER T_AfterDelete_ON_AccountTransaction
    AFTER DELETE ON AccountTransaction
    FOR EACH ROW
    BEGIN
        DELETE FROM AccountTradePays WHERE pSerial = "AT-" + OLD.tId;
    END||
DELIMITER;

DELIMITER &&
    CREATE TRIGGER tri_memory_delete AFTER DELETE ON T FOR EACH ROW
    BEGIN
        DELETE From tempT where tempT.id = OLD.id;
    END &&
DELIMITER ;

DECLARE vv varchar(20);
    set vv=InsertToEmail(names,"zyff@iirii.com");
    INSERT INTO user_info (name,age,email,addr) VALUES(names,33,"zyf@iirii.com","湖北东西湖");


BEGIN
    DECLARE vv varchar(20);
    set vv=InsertToEmail(names,"zyff@iirii.com");
    INSERT INTO user_info (name,age,email,addr) VALUES(names,33,"zyf@iirii.com","湖北东西湖");
END

BEGIN
    DECLARE vv varchar(20);
    DECLARE vvv varchar(20);
    set vv=InsertToUploadsFun(names,"zyfffff@iirii.com");
    set vvv=InsertToEmailFun(names);
    INSERT INTO user_info (name,age,email,addr) VALUES(names,33,"zyf@iirii.com","湖北东西湖");
END

BEGIN
  DECLARE asId varchar(20);
  SET asId = CONCAT("C-",NEW.Id);
  SET @ret= redis_command_v2("HSET","crmInboxEventsS",asId,
                            json_object
                            (
                                  json_members
                                  (
                                          "op",
                                          "insert",
                                          "asId",
                                          asId,
                                          "value",
                                          json_object
                                          (
                                              NEW.Id as "id",NEW.type as "type",
                                              NEW.mailserver_id as "mailserverId",NEW.sender as "sender",
                                              NEW.sender_name as "senderName",NEW.recevier as "recevier",
                                              NEW.replyto as "replyto",NEW.bbemails as "bbemails",
                                              NEW.ccemails as "ccemails",NEW.subject as "subject"
                                          )
                                      )
                              )
                        );
END

BEGIN
  DECLARE asId varchar(20);
  SET asId = CONCAT("C-",NEW.Id);
  SET @ret= redis_command_v2("HSET","crmInboxEventsS",asId,
               json_object
               (
                   NEW.Id as "id",NEW.type as "type",
                   NEW.mailserver_id as "mailserverId",NEW.sender as "sender",
                   NEW.sender_name as "senderName",NEW.recevier as "recevier",
                   NEW.replyto as "replyto",NEW.bbemails as "bbemails",
                   NEW.ccemails as "ccemails",NEW.subject as "subject"
               )
  );
END

参考列表
MySQL触发器

Android 推送之 MQTT

Android 开发推送方案

MQTT 服务器

使用 emqttd broken
GitHub - emqtt/emqttd
官网

emqttd 主要配置参数

emqttd 使用以下命令调试输出

./bin/emqttd console

如果没有打印输出日志信息,可以参考取消 rel/files/emqttd.config.production 或 ./etc/emqttd.config 中对 %%{lager_console_backend, info} 的注释
关于提问


MQTT Android 客户端

之前使用 IBM 提供的 wmqtt.jar 和 tokudu 项目示例

wmqtt.jar
tokudu/AndroidPushNotificationsDemo

由于 wmqttd 几乎没有更新,于是采用新的Android客户端 Paho 方案

需要添加如下两个依赖 org.eclipse.paho:org.eclipse.paho.client.mqttv3org.eclipse.paho:org.eclipse.paho.android.service

1
2
3
4
5
6
7
8
dependencies {
// http://www.eclipse.org/paho/clients/android/
compile('org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.0.2')
compile('org.eclipse.paho:org.eclipse.paho.android.service:1.0.2') {
exclude module: "org.eclipse.paho.client.mqttv3", group: "org.eclipse.paho"
exclude module: "support-v4", group: "com.google.android"
}
}

比较好的参考演示项目:
jeffprestes/AndroidMQTTDemo
样例使用示例

其它
MQTT协议实现Eclipse Paho学习总结一
编写和MQTT服务器通信的Android客户端程序(二)
MQTT协议之订阅及发布(使用paho-mqtt-client或mqttv3实现)


服务器 PHP 客户端 SAM

SAM 针对MQTT写的PHP库 (下载链接为Tokudu PHPMQTT通信项目),其中send_mqtt.php是一个通过POST接收消息并且通过SAM将消息发送给RSMB的PHP脚本.
SAM

参考 tokudu 项目
tokudu/PhpMQTTClient
bluerhinos/phpMQTT


MQTT协议笔记之连接和心跳

几种 MQTT 协议 包 格式有: 连接(CONNECT). 心跳(PINGREQ/PINGRESP). 确认(CONNACK). 断开连接(DISCONNECT). 订阅(SUBSCRIBE). 取消订阅(SUBACK)


参考

mqtt 协议之 PINGREQ, PINGRESP
MQTT协议笔记之连接和心跳

Android消息推送完美方案

Title

phpMyAdmin 相关

http://www.phpmyadmin.net/
phpmyadmin/phpmyadmin

  • 安装
1
2
sudo wget https://github.com/phpmyadmin/phpmyadmin/archive/RELEASE_4_6_1.zip
unzip RELEASE_4_6_1.zip
  • 修改phpMyAdmin中的默认1440超时时间
  1. 修改PHP配置中 session 的过期时间.
1
2
3
session.gc_maxlifetime = 1440
# 改为
session.gc_maxlifetime = 86400
  1. 修改phpMyAdmin配置中 session 的过期时间.

找到并修改 phpMyAdmin/libraries/config.default.php 文件

1
2
3
$cfg['LoginCookieValidity'] = 1440;
// 改为
$cfg['LoginCookieValidity'] = 86400;

注意:

$cfg[‘LoginCookieValidity’] 的值不能大于 php.ini 里的 session.gc_maxlifetime 的值,否则 phpmyadmin 里会出现”您的 PHP 配置参数 session.gc_maxlifetime (外链,英文) 短于您在 phpMyAdmin 中设置的 Cookies 有效期,此您的登录会话有效期将会比您在 phpMyAdmin 中设置的时间要更短.

Title

android上的JAVA8:使用retrolambda - (一个让android支持lambda语法的扩展框架)

retrolambda GitHub
gradle-retrolambda plugin
android上的JAVA8:使用retrolambda
jdk1.8新特性之lambda表达式及在Android Studio中的使用

Java8 lambda表达式10个示例
Java 8简明教程

Java8引入了 lambda 表达式,让许多开发者激动不已,本文介绍如何在Android上使用lambda.

首先下载 java8 sdk,并且配置完成
在 build.gradle 中加入编译的依赖,这会使用 retrolambda 来编译Java代码

buildscript {
    //开始加入
    dependencies {
        classpath 'me.tatarka:gradle-retrolambda:3.1.0'
    }
    //结束插入
}

同时要加入plugin声明

apply plugin: 'me.tatarka.retrolambda'

3 . 加入compileOptions,这会让IDE使用用JAVA8语法解析

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

4 . 指定将源码编译的级别,,使用下列代码,会将代码编译到兼容1.6的字节码格式

retrolambda {
    javaVersion JavaVersion.VERSION_1_6
}

5 . 添加测试代码, 对于只有一个方法的接口,java8中可以使用lambda表达式代替,所以我们熟悉的设定View点击事件的代码,只要这样写就可以了

v.setOnClickListener(v1 -> Toast.makeText(getActivity(), "clicked", Toast.LENGTH_LONG).show());

对比一下之前的代码量,是不是爽爆了?!!

v.setOnClickListener(new View.OnClickListener(View v) {
@Override
    public void onClick(View v) {
        Toast.makeText(getActivity(), "clicked", Toast.LENGTH_LONG).show()
    }
});

所有代码可以在这里找到:

http://tinyurl.com/qdbae7d

retrolambda配置参考
jdk1.8新特性之lambda表达式及在Android Studio中的使用
Java 8简明教程

问题分析

Lint fails on java files that have lambdas.

由于Android’s lint doesn’t understand java 8 syntax and will fail silently or loudly.
evant/android-retrolambda-lombok

Title

使用Gradle管理你的Android Studio工程

重点*Gradle多渠道和自动化打包(基础篇).md
重点*Gradle中文文档
使用Gradle管理你的Android Studio工程
使用Gradle构建Android项目
Gradle里的三种依赖
快速了解AndroidStudio的Gradle
Gradle 构建 android 应用常见问题解决指南
Gradle学习
快速掌握 Android Studio 中 Gradle 的使用方法

Don’t use dynamic versions for your dependencies

Gradle学习笔记(Android)
Android开发之Gradle笔记整理1
Android开发之Gradle笔记整理2——Gradle常用命令及UMeng多渠道打包实战


[提高 Android Studio 编译速度]

加快Android Studio的编译速度
优化android-studio编译效率的方法.md

任务task的执行

通常会有以下任务:

assemble The task to assemble the output(s) of the project(输出一个项目文件,android就是打包apk)

check The task to run all the checks.(运行检查,检查程序的错误,语法,等等)

build This task does both assemble and check (执行assemble和check)

clean This task cleans the output of the project(清理项目输出文件)

其它命令参考:
./gradlew build
./gradlew assemble
./gradlew assembleInnderDebug

查看其他所有依赖关系

Don’t use dynamic versions for your dependencies
$ ./gradlew :app:dependencies
$ ./gradlew androidDependencies
$ ./gradlew buildscriptDependencies

使用 gradlew compileDebug –stacktrace 命令调试查看输出 参考 Android Studio and Gradle build error

apk 应用打包签名相关

查看密钥库证书指纹SHA1

keytool -list -keystore coam.jks

Certificate fingerprints:
         MD5:  F1:DB:A0:07:72:4F:CC:1C:27:7A:83:AC:F0:01:04:18
         SHA1: B1:4E:98:0F:87:40:90:2B:C5:90:33:2C:1E:A2:9A:4E:95:8B:A0:C7
         SHA256: C2:FF:23:E8:18:11:3B:9C:6D:1C:DA:17:35:5D:A3:C8:DB:04:58:5F:8A:3B:C9:C2:0C:72:4D:F3:C6:A0:17:D9
         Signature algorithm name: SHA256withRSA
         Version: 3

旧版,李邦提供

md5: b11b96e0ca39d6ed04cbaefd29edadae这个是正式的签名,md5: 63ef90a0e13362902e7482673fe37df9这个是我机子上的测试签名


Android App Proguard …

Refresh

使用proguard混淆android代码
AndroidStudio下ProGuard混淆打包
ProGuard基础语法和打包配置
http://stackoverflow.com/questions/25314202/proguard-build-failure-with-lombok-annotation-library

Title

AndroidFragment 相关

Android Fragment 生命周期图
Fragment生命周期详解
我为什么主张反对使用Android Fragment
Fragment专题.md
Fragment笔记整理


Fragment 结合 DrawerLayout

Fragment Navigation Drawer


Fragment 旋屏及配置改变 运行数据保存问题

半分钟读完]Android中保存和恢复Fragment状态的最好方法
保存和恢复 Android Fragment 的状态
用Fragment解决屏幕旋转(状态发生变化)状态不能保持的问题
The Real Best Practices to Save/Restore Activity’s and Fragment’s state. (StatedFragment is now deprecated)
onSaveInstanceState和onRestoreInstanceState在Activity生命周期中的位置


ViewPager 和 Fragment 使用注意的问题
使用 ViewPager 和 Fragment 遇到的问题

在 Fragment 中使用 ViewPager 加载子 Fragment 一定要使用 getChildFragmentManager() 而不应该是 getSupportFragmentManager(),否则会出现切换后不显示内容


让多个Fragment 切换时不重新实例化


Fragment 设置Tag和Id的两种方式

Fragment tags are not automatically specified. You have to assign them yourself. There are several places to do it depending on how you attach fragment: in the XML or dynamically.

一. If it’s define in XML then you can set it like this:

1
2
3
4
5
6
<fragment android:name="com.example.news.ArticleListFragment"
android:id="@+id/list"
android:tag="your_tag"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />

二. If you add fragment dynamically then you can do it like this:

1
2
3
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment, "your_tag");
fragmentTransaction.commit();

两种方式均设定相同的Tag “your_tag”.