MQTT v5 draft features

The MQTT Technical Committee at OASIS continue to work on improvements to MQTT. The next version looks set to be MQTT version 5 and has reached the “working draft” stage. This post lists some of the changes that are in the working draft 02 and so gives at least a flavour of the improvements coming up. Take this with a pinch of salt, I may have missed some changes and there is no commitment that any of these features will remain in the final specification as they are described here.

Session management

In MQTT v3.1.1 and earlier, a client could control how the server treats its session with the clean session flag. If set to 1, the server would delete any existing session for that client and would not persist the session after disconnecting. If set to 0, the server would restore any existing session for a client when it reconnected, and persist the session when the client disconnected.

A session here means the subscriptions for a client and any queued messages.

The new spec changes this behaviour. The clean session flag has been renamed to clean start (this was actually the name of the flag in the old MQTT v3 spec) and now only affects how the broker handles a client session when the client connects. If set to 1, the server discards any previous session information, otherwise session information is kept.

To deal with removing of sessions at any other time, a new identifier/value pair has been introduced. These identifier/value pairs are an addition to the variable header part of some MQTT packets and allow configuring of different behaviour. In the case of the CONNECT packet, a Session Expiry interval can be specified which is a 4 byte integer that gives the number of seconds after a client has disconnected that the server should remove session information for that client. If the Session Expiry interval is absent from the CONNECT packet, then the session will never expire. If it is set to 0, then the session is removed as soon as the client disconnects.

The new clean start flag and session expiry interval allow the existing clean session behaviour to be duplicated but also allow client sessions to be expired based on time.

Updated Connect Return codes

The return codes passed to the client in a CONNACK packet have been expanded to include:

  • 6: Connection Refused, reason unspecified
  • 7: Connection Refused, implementation specific
  • 8: Connection Refused, CONNECT packet was malformed

Repeated topics when publishing

When publishing data to a single topic, a new feature will help reduce bandwidth use. A client or server can set the topic in a PUBLISH message to be a zero length string. This tells the client/server being published to, to use the previous topic instead. This goes some way to reducing the current overhead associated with publishing – a shame it isn’t quite as good as the registered topics available in MQTT-SN.

Payload Format Indicator

Another identifier/value pair is available for use when sending a PUBLISH message. This is the Payload Format indicator. If present and set to 1, this indicates that the PUBLISH payload is UTF-8 encoded data. If set to 0, or if the indicator is not present then the payload is an unspecified byte format, exactly as with MQTT v3.1.1.

Publication Expiry interval

This is an identifier/value pair for use when publishing. If present, this value is a 4 byte integer which gives the number of seconds for which the server will attempt to deliver this message to a subscriber. This means that an offline client with messages being queued may not receive all of the messages when it reconnects, due to some of them expiring. Interestingly, when the server does deliver a message that had a Publication Expiry set, it sets the Publication Expiry on the outgoing message to the client but with the amount of time that there is left until the message expires. This means that the true time to expiry will propagate through bridges or similar.

Publish Return Codes

The PUBACK and PUBREC packets have a new entry in their variable header which is the Publish Return Code. This can be used to tell the client a message has been refused for various reasons, accepted, or accepted with no matching subscribers.  For the PUBREC packet, if the message is refused or accepted with no matching subscribers then there is no expectation for the PUBREL/PUBCOMP messages to be sent for that message.

The PUBCOMP packet also has a similar entry which has the same set of return codes and an additional one for the case when a message had expired. This is for the case when a client reconnects with clean start set to 0 and it has a QoS 2 message part way through its handshake, but the server has already expired the message.

There is still no way to tell a client that its QoS 0 message was refused.

Disconnect notification

In MQTT v3.1.1 and before, only the client sends a DISCONNECT packet. In the draft spec, either the client or the server can send DISCONNECT and it is used to indicate a reason for disconnection. The disconnect return codes are:

  • 0: Connection disconnected by application (sent by client)
  • 1: Server temporarily unavailable (server)
  • 2: Server unavailable (server)
  • 3: Malformed UNSUBSCRIBE packet received (server)
  • 4: Session taken over (server – for when another client connects with the same ID)
  • 5: Malformed packet received

It is clear that there is some duplication there, so I think this is a likely place that changes will be made.

Disconnect expiry notification

The DISCONNECT packet can also include a Session Expiry interval value, as with CONNECT. This allows a client to clean up when it disconnects, or to set a long expiry time, even if these were not specified at the initial connect.

发表在 Linux | 留下评论

10 个很有用的高级 git 命令


1. 输出最后一次提交的改变

这个命令,我经常使用它 来发送其他没有使用git的人来检查或者集成所修改的。它会输出最近提交的修改内容到一个zip文件中。

git archive -o ../ HEAD $(git diff --name-only HEAD^)

2. 输出两个提交间的改变


1 git archive -o ../ NEW_COMMIT_ID_HERE $(git diff --name-only OLD_COMMIT_ID_HERE NEW_COMMIT_ID_HERE)

3. 克隆 指定的远程分支


1 git init
2 git remote add -t BRANCH_NAME_HERE -f origin REMOTE_REPO_URL_PATH_HERE
3 git checkout BRANCH_NAME_HERE

4. 应用 从不相关的本地仓库来的补丁


1 git --git-dir=PATH_TO_OTHER_REPOSITORY_HERE/.git format-patch -k -1 --stdout COMMIT_HASH_ID_HERE| git am -3 -k

5. 检测 你的分支的改变是否为其它分支的一部分

cherry命令让我们检测你的分支的改变是否出现在其它一些分支中。它通过+或者-符号来显示从当前分支与所给的分支之间的改变:是否合并了(merged)。.+ 指示没有出现在所给分支中,反之,- 就表示出现在了所给的分支中了。这里就是如何去检测:

1 git cherry -v OTHER_BRANCH_NAME_HERE
2 #例如: 检测master分支
3 git cherry -v master



1 git checkout --orphan NEW_BRANCH_NAME_HERE

7. 无切换分支的从其它分支Checkout文件





1 git update-index --assume-unchanged PATH_TO_FILE_HERE



1 git name-rev --name-only COMMIT_HASH_HERE



1 git pull --rebase


1 git config branch.BRANCH_NAME_HERE.rebase true
发表在 Linux | 留下评论

常用 git 命令清单


我每天使用 Git ,但是很多命令记不住。


下面是我整理的常用 Git 命令清单。几个专用名词的译名如下。

  • Workspace:工作区
  • Index / Stage:暂存区
  • Repository:仓库区(或本地仓库)
  • Remote:远程仓库


# 在当前目录新建一个Git代码库
$ git init

# 新建一个目录,将其初始化为Git代码库
$ git init [project-name]

# 下载一个项目和它的整个代码历史
$ git clone [url]



# 显示当前的Git配置
$ git config --list

# 编辑Git配置文件
$ git config -e [--global]

# 设置提交代码时的用户信息
$ git config [--global] "[name]"
$ git config [--global] "[email address]"


# 添加指定文件到暂存区
$ git add [file1] [file2] ...

# 添加指定目录到暂存区,包括子目录
$ git add [dir]

# 添加当前目录的所有文件到暂存区
$ git add .

# 添加每个变化前,都会要求确认
# 对于同一个文件的多处变化,可以实现分次提交
$ git add -p

# 删除工作区文件,并且将这次删除放入暂存区
$ git rm [file1] [file2] ...

# 停止追踪指定文件,但该文件会保留在工作区
$ git rm --cached [file]

# 改名文件,并且将这个改名放入暂存区
$ git mv [file-original] [file-renamed]


# 提交暂存区到仓库区
$ git commit -m [message]

# 提交暂存区的指定文件到仓库区
$ git commit [file1] [file2] ... -m [message]

# 提交工作区自上次commit之后的变化,直接到仓库区
$ git commit -a

# 提交时显示所有diff信息
$ git commit -v

# 使用一次新的commit,替代上一次提交
# 如果代码没有任何新变化,则用来改写上一次commit的提交信息
$ git commit --amend -m [message]

# 重做上一次commit,并包括指定文件的新变化
$ git commit --amend [file1] [file2] ...


# 列出所有本地分支
$ git branch

# 列出所有远程分支
$ git branch -r

# 列出所有本地分支和远程分支
$ git branch -a

# 新建一个分支,但依然停留在当前分支
$ git branch [branch-name]

# 新建一个分支,并切换到该分支
$ git checkout -b [branch]

# 新建一个分支,指向指定commit
$ git branch [branch] [commit]

# 新建一个分支,与指定的远程分支建立追踪关系
$ git branch --track [branch] [remote-branch]

# 切换到指定分支,并更新工作区
$ git checkout [branch-name]

# 切换到上一个分支
$ git checkout -

# 建立追踪关系,在现有分支与指定的远程分支之间
$ git branch --set-upstream [branch] [remote-branch]

# 合并指定分支到当前分支
$ git merge [branch]

# 选择一个commit,合并进当前分支
$ git cherry-pick [commit]

# 删除分支
$ git branch -d [branch-name]

# 删除远程分支
$ git push origin --delete [branch-name]
$ git branch -dr [remote/branch]


# 列出所有tag
$ git tag

# 新建一个tag在当前commit
$ git tag [tag]

# 新建一个tag在指定commit
$ git tag [tag] [commit]

# 删除本地tag
$ git tag -d [tag]

# 删除远程tag
$ git push origin :refs/tags/[tagName]

# 查看tag信息
$ git show [tag]

# 提交指定tag
$ git push [remote] [tag]

# 提交所有tag
$ git push [remote] --tags

# 新建一个分支,指向某个tag
$ git checkout -b [branch] [tag]


# 显示有变更的文件
$ git status

# 显示当前分支的版本历史
$ git log

# 显示commit历史,以及每次commit发生变更的文件
$ git log --stat

# 搜索提交历史,根据关键词
$ git log -S [keyword]

# 显示某个commit之后的所有变动,每个commit占据一行
$ git log [tag] HEAD --pretty=format:%s

# 显示某个commit之后的所有变动,其"提交说明"必须符合搜索条件
$ git log [tag] HEAD --grep feature

# 显示某个文件的版本历史,包括文件改名
$ git log --follow [file]
$ git whatchanged [file]

# 显示指定文件相关的每一次diff
$ git log -p [file]

# 显示过去5次提交
$ git log -5 --pretty --oneline

# 显示所有提交过的用户,按提交次数排序
$ git shortlog -sn

# 显示指定文件是什么人在什么时间修改过
$ git blame [file]

# 显示暂存区和工作区的差异
$ git diff

# 显示暂存区和上一个commit的差异
$ git diff --cached [file]

# 显示工作区与当前分支最新commit之间的差异
$ git diff HEAD

# 显示两次提交之间的差异
$ git diff [first-branch]...[second-branch]

# 显示今天你写了多少行代码
$ git diff --shortstat "@{0 day ago}"

# 显示某次提交的元数据和内容变化
$ git show [commit]

# 显示某次提交发生变化的文件
$ git show --name-only [commit]

# 显示某次提交时,某个文件的内容
$ git show [commit]:[filename]

# 显示当前分支的最近几次提交
$ git reflog


# 下载远程仓库的所有变动
$ git fetch [remote]

# 显示所有远程仓库
$ git remote -v

# 显示某个远程仓库的信息
$ git remote show [remote]

# 增加一个新的远程仓库,并命名
$ git remote add [shortname] [url]

# 取回远程仓库的变化,并与本地分支合并
$ git pull [remote] [branch]

# 上传本地指定分支到远程仓库
$ git push [remote] [branch]

# 强行推送当前分支到远程仓库,即使有冲突
$ git push [remote] --force

# 推送所有分支到远程仓库
$ git push [remote] --all


# 恢复暂存区的指定文件到工作区
$ git checkout [file]

# 恢复某个commit的指定文件到暂存区和工作区
$ git checkout [commit] [file]

# 恢复暂存区的所有文件到工作区
$ git checkout .

# 重置暂存区的指定文件,与上一次commit保持一致,但工作区不变
$ git reset [file]

# 重置暂存区与工作区,与上一次commit保持一致
$ git reset --hard

# 重置当前分支的指针为指定commit,同时重置暂存区,但工作区不变
$ git reset [commit]

# 重置当前分支的HEAD为指定commit,同时重置暂存区和工作区,与指定commit一致
$ git reset --hard [commit]

# 重置当前HEAD为指定commit,但保持暂存区和工作区不变
$ git reset --keep [commit]

# 新建一个commit,用来撤销指定commit
# 后者的所有变化都将被前者抵消,并且应用到当前分支
$ git revert [commit]

# 暂时将未提交的变化移除,稍后再移入
$ git stash
$ git stash pop


# 生成一个可供发布的压缩包
$ git archive
发表在 Linux | 留下评论



很早之前,我们就提到过用git tag来给工程打上标签,但是这个命令只是在本地仓库打标签而已,



默认情况下,git push并不会把tag标签传送到远端服务器上,只有通过显式命令才能分享标签到远端仓库。
1.push单个tag,命令格式为:git push origin [tagname]
git push origin v1.0 #将本地v1.0的tag推送到远端服务器
2.push所有tag,命令格式为:git push [origin] –tags
git push –tags

git push origin –tags


发表在 Linux | 留下评论

A successful Git branching model

In this post I present the development model that I’ve introduced for some of my projects (both at work and private) about a year ago, and which has turned out to be very successful. I’ve been meaning to write about it for a while now, but I’ve never really found the time to do so thoroughly, until now. I won’t talk about any of the projects’ details, merely about the branching strategy and release management.


It focuses around Git as the tool for the versioning of all of our source code. (By the way, if you’re interested in Git, our company GitPrime provides some awesome realtime data analytics on software engineering performance.)

Why git?

For a thorough discussion on the pros and cons of Git compared to centralized source code control systems, see the web. There are plenty of flame wars going on there. As a developer, I prefer Git above all other tools around today. Git really changed the way developers think of merging and branching. From the classic CVS/Subversion world I came from, merging/branching has always been considered a bit scary (“beware of merge conflicts, they bite you!”) and something you only do every once in a while.

But with Git, these actions are extremely cheap and simple, and they are considered one of the core parts of your daily workflow, really. For example, in CVS/Subversion books, branching and merging is first discussed in the later chapters (for advanced users), while in every Git book, it’s already covered in chapter 3 (basics).

As a consequence of its simplicity and repetitive nature, branching and merging are no longer something to be afraid of. Version control tools are supposed to assist in branching/merging more than anything else.

Enough about the tools, let’s head onto the development model. The model that I’m going to present here is essentially no more than a set of procedures that every team member has to follow in order to come to a managed software development process.

Decentralized but centralized

The repository setup that we use and that works well with this branching model, is that with a central “truth” repo. Note that this repo is only considered to be the central one (since Git is a DVCS, there is no such thing as a central repo at a technical level). We will refer to this repo as origin, since this name is familiar to all Git users.


Each developer pulls and pushes to origin. But besides the centralized push-pull relationships, each developer may also pull changes from other peers to form sub teams. For example, this might be useful to work together with two or more developers on a big new feature, before pushing the work in progress to origin prematurely. In the figure above, there are subteams of Alice and Bob, Alice and David, and Clair and David.

Technically, this means nothing more than that Alice has defined a Git remote, named bob, pointing to Bob’s repository, and vice versa.

The main branches


At the core, the development model is greatly inspired by existing models out there. The central repo holds two main branches with an infinite lifetime:

  • master
  • develop

The master branch at origin should be familiar to every Git user. Parallel to the master branch, another branch exists called develop.

We consider origin/master to be the main branch where the source code of HEAD always reflects a production-ready state.

We consider origin/develop to be the main branch where the source code of HEAD always reflects a state with the latest delivered development changes for the next release. Some would call this the “integration branch”. This is where any automatic nightly builds are built from.

When the source code in the develop branch reaches a stable point and is ready to be released, all of the changes should be merged back into master somehow and then tagged with a release number. How this is done in detail will be discussed further on.

Therefore, each time when changes are merged back into master, this is a new production releaseby definition. We tend to be very strict at this, so that theoretically, we could use a Git hook script to automatically build and roll-out our software to our production servers everytime there was a commit on master.

Supporting branches

Next to the main branches master and develop, our development model uses a variety of supporting branches to aid parallel development between team members, ease tracking of features, prepare for production releases and to assist in quickly fixing live production problems. Unlike the main branches, these branches always have a limited life time, since they will be removed eventually.

The different types of branches we may use are:

  • Feature branches
  • Release branches
  • Hotfix branches

Each of these branches have a specific purpose and are bound to strict rules as to which branches may be their originating branch and which branches must be their merge targets. We will walk through them in a minute.

By no means are these branches “special” from a technical perspective. The branch types are categorized by how we use them. They are of course plain old Git branches.

Feature branches


May branch off from:
Must merge back into:
Branch naming convention:
anything except master, develop, release-*, or hotfix-*

Feature branches (or sometimes called topic branches) are used to develop new features for the upcoming or a distant future release. When starting development of a feature, the target release in which this feature will be incorporated may well be unknown at that point. The essence of a feature branch is that it exists as long as the feature is in development, but will eventually be merged back into develop (to definitely add the new feature to the upcoming release) or discarded (in case of a disappointing experiment).

Feature branches typically exist in developer repos only, not in origin.

Creating a feature branch

When starting work on a new feature, branch off from the develop branch.

$ git checkout -b myfeature develop
Switched to a new branch "myfeature"

Incorporating a finished feature on develop

Finished features may be merged into the develop branch to definitely add them to the upcoming release:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557).
$ git push origin develop

The --no-ff flag causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward. This avoids losing information about the historical existence of a feature branch and groups together all commits that together added the feature. Compare:


In the latter case, it is impossible to see from the Git history which of the commit objects together have implemented a feature—you would have to manually read all the log messages. Reverting a whole feature (i.e. a group of commits), is a true headache in the latter situation, whereas it is easily done if the --no-ff flag was used.

Yes, it will create a few more (empty) commit objects, but the gain is much bigger than the cost.

Release branches

May branch off from:
Must merge back into:
develop and master
Branch naming convention:

Release branches support preparation of a new production release. They allow for last-minute dotting of i’s and crossing t’s. Furthermore, they allow for minor bug fixes and preparing meta-data for a release (version number, build dates, etc.). By doing all of this work on a release branch, thedevelop branch is cleared to receive features for the next big release.

The key moment to branch off a new release branch from develop is when develop (almost) reflects the desired state of the new release. At least all features that are targeted for the release-to-be-built must be merged in to develop at this point in time. All features targeted at future releases may not—they must wait until after the release branch is branched off.

It is exactly at the start of a release branch that the upcoming release gets assigned a version number—not any earlier. Up until that moment, the develop branch reflected changes for the “next release”, but it is unclear whether that “next release” will eventually become 0.3 or 1.0, until the release branch is started. That decision is made on the start of the release branch and is carried out by the project’s rules on version number bumping.

Creating a release branch

Release branches are created from the develop branch. For example, say version 1.1.5 is the current production release and we have a big release coming up. The state of develop is ready for the “next release” and we have decided that this will become version 1.2 (rather than 1.1.6 or 2.0). So we branch off and give the release branch a name reflecting the new version number:

$ git checkout -b release-1.2 develop
Switched to a new branch "release-1.2"
$ ./ 1.2
Files modified successfully, version bumped to 1.2.
$ git commit -a -m "Bumped version number to 1.2"
[release-1.2 74d9424] Bumped version number to 1.2
1 files changed, 1 insertions(+), 1 deletions(-)

After creating a new branch and switching to it, we bump the version number. Here, is a fictional shell script that changes some files in the working copy to reflect the new version. (This can of course be a manual change—the point being that some files change.) Then, the bumped version number is committed.

This new branch may exist there for a while, until the release may be rolled out definitely. During that time, bug fixes may be applied in this branch (rather than on the develop branch). Adding large new features here is strictly prohibited. They must be merged into develop, and therefore, wait for the next big release.

Finishing a release branch

When the state of the release branch is ready to become a real release, some actions need to be carried out. First, the release branch is merged into master (since every commit on master is a new release by definition, remember). Next, that commit on master must be tagged for easy future reference to this historical version. Finally, the changes made on the release branch need to be merged back into develop, so that future releases also contain these bug fixes.

The first two steps in Git:

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2

The release is now done, and tagged for future reference.

Edit: You might as well want to use the -s or -u <key> flags to sign your tag cryptographically.

To keep the changes made in the release branch, we need to merge those back into develop, though. In Git:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)

This step may well lead to a merge conflict (probably even, since we have changed the version number). If so, fix it and commit.

Now we are really done and the release branch may be removed, since we don’t need it anymore:

$ git branch -d release-1.2
Deleted branch release-1.2 (was ff452fe).

Hotfix branches


May branch off from:
Must merge back into:
develop and master
Branch naming convention:

Hotfix branches are very much like release branches in that they are also meant to prepare for a new production release, albeit unplanned. They arise from the necessity to act immediately upon an undesired state of a live production version. When a critical bug in a production version must be resolved immediately, a hotfix branch may be branched off from the corresponding tag on the master branch that marks the production version.

The essence is that work of team members (on thedevelop branch) can continue, while another person is preparing a quick production fix.

Creating the hotfix branch

Hotfix branches are created from the master branch. For example, say version 1.2 is the current production release running live and causing troubles due to a severe bug. But changes on developare yet unstable. We may then branch off a hotfix branch and start fixing the problem:

$ git checkout -b hotfix-1.2.1 master
Switched to a new branch "hotfix-1.2.1"
$ ./ 1.2.1
Files modified successfully, version bumped to 1.2.1.
$ git commit -a -m "Bumped version number to 1.2.1"
[hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1
1 files changed, 1 insertions(+), 1 deletions(-)

Don’t forget to bump the version number after branching off!

Then, fix the bug and commit the fix in one or more separate commits.

$ git commit -m "Fixed severe production problem"
[hotfix-1.2.1 abbe5d6] Fixed severe production problem
5 files changed, 32 insertions(+), 17 deletions(-)

Finishing a hotfix branch

When finished, the bugfix needs to be merged back into master, but also needs to be merged back into develop, in order to safeguard that the bugfix is included in the next release as well. This is completely similar to how release branches are finished.

First, update master and tag the release.

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2.1

Edit: You might as well want to use the -s or -u <key> flags to sign your tag cryptographically.

Next, include the bugfix in develop, too:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)

The one exception to the rule here is that, when a release branch currently exists, the hotfix changes need to be merged into that release branch, instead of develop. Back-merging the bugfix into the release branch will eventually result in the bugfix being merged into develop too, when the release branch is finished. (If work in develop immediately requires this bugfix and cannot wait for the release branch to be finished, you may safely merge the bugfix into develop now already as well.)

Finally, remove the temporary branch:

$ git branch -d hotfix-1.2.1
Deleted branch hotfix-1.2.1 (was abbe5d6).


While there is nothing really shocking new to this branching model, the “big picture” figure that this post began with has turned out to be tremendously useful in our projects. It forms an elegant mental model that is easy to comprehend and allows team members to develop a shared understanding of the branching and releasing processes.

A high-quality PDF version of the figure is provided here. Go ahead and hang it on the wall for quick reference at any time.

Update: And for anyone who requested it: here’s the gitflow-model.src.key of the main diagram image (Apple Keynote).

If you want to get in touch, I’m @nvie on Twitter.

发表在 Linux | 留下评论

android 关闭spell check

If your using Android Studio 1.1.0, then spell check can be customized/disable via:

File -> Settings (Project Settings […]) -> Inspections -> Spelling -> Type

This brings up three options that can be enabled/disabled:

  1. Process code
  2. Process literals
  3. Process comments

You can disable all by deselecting the Typo check box

发表在 android | 留下评论

MQTT Client Library Enyclopedia – Paho Android Service


Guest post by Sandro Kock

Pahao Android Service
Language Java
License Eclipse Public License v1.0 and Eclipse Distribution License v1.0
API Style Asynchronous


The Paho Android Service is an interface to the Paho Java MQTT Client library for the Android Platform. The MQTT connection is encapsulated within an Android-Service that runs in the background of the Android application, keeping it alive when the Android application is switching between different Activities. This layer of abstraction is needed to be able to receive MQTT messages reliably. As the Paho Android Service is based on the Paho Java client library it can be considered stable and used in production. The project is actively maintained by the Eclipse Paho project.


MQTT 3.1 ok
MQTT 3.1.1 ok
LWT ok
Automatic Reconnect nok (On the road map)
QoS 0 ok
QoS 1 ok
QoS 2 ok
Authentication ok
Throttling nok



Android uses Gradle as a build system and dependency management, therefor this blog post describes how the Paho Android Service can be added to an application via Gradle. The most convenient way to start a new Android Application is to use Android Studio. To add the Paho Android Service as a dependency to you app add the following parts to your gradle file.

The first part adds the Paho release repository to the gradle config, so that Gradle is able to find the packaged Paho Android Service JAR. The second part adds the Paho Android Service as a dependency to the application. The exclusion of the Android Support library exclude module: 'support-v4' is only necessary if the Android application is using the Android Support Library to backport newer Android features to older Android versions. To have the latest Snapshot release within your application the gradle config below can be used.


As already mentioned, the Paho Android Service encapsulates the MQTT connection and offers an API for that. To be able to create a binding to the Paho Android Service, the service needs to be declared in theAndroidManifest.xml. Add the following within the <application> tag:

The Paho Android Service needs the following permissions to work:

Add those to the <manifest> tag.

Usually an Android Activity requests or binds to an Android Service to use it, for e.g. the LocationManager to receive updates when the GPS position of the user changes. The Paho Android Service is not meant to bind to directly. Instead the provided MqttAndroidClient client interface binds to the service once created. To create and establish an MQTT-connection use the following code snipped:

In the first line a helper Function of the Paho MQTT client is used to generate a random user id. The second line creates an instance of an Android MQTT client, that will bind to the Paho Android Service. By calling the connectmethod of the MqttAndroidClient the client will asynchronously try to connect to the MQTT broker and return a token. That token can be used to register callbacks, to get notified when either the MQTT-connection gets connected or an error occurs. Running the above example inside an Android Activity.onCreate method will print “onSuccess” or “onFailure” to the console.

Connect with MQTT 3.1 or MQTT 3.1.1

The MqttAndroidClient will connect with MQTT 3.1.1 by default, with a fallback to 3.1. To intentionally connect with MQTT 3.1 a MqttConnectOptions object can be supplied to the connect method:

Connect with LWT

Like the MQTT version, the Last Will And Testament (LWT) can be added into the MqttConnectOptions object.

Besides the payload of the LWT, everything is straight forward and can be just set. Many MQTT clients assume that the payload is an UTF-8 formatted string and convert the payload automatically. The fact that MQTT is a binary protocol is often hidden with that. By calling String#getBytes the string will be encoded with the systems default charset (UTF-8 on Android).

Connect with Username / Password

Again like the MQTT version and the LWT, the username and password can be supplied within the options object.


The MqttAndroidClient allows messages to be published via its publish(topic, MqttMessage) method. By design the MqttAndroidClient dose not queue any messages if the client is not connected and will throw an error when trying to send messages when the client is offline client.isConnected() == false. After the first connect, the IMqttActionListener.onSuccess method is called when a MQTT connection is established successfully.

Publish a retained message

To send a retained MQTT message the MqttMessage.retained attribute can be set to true viaMqttMessage.setRetained(true).


Subscriptions can be created via the MqttAndroidClient.subscribe method, which takes the topic and the QOS as parameters and returns a IMqttToken. The token can be used to keep track if the subscription can successfully established or failed. The example below subscribes to the topic “foo/bar” with QOS 1



To disconnect the client call the disconnect method of the MqttAndroidClient object. The example below saves the token returned by the disconnect method and adds a IMqttActionListener to get notified when the client is successfully disconnected.

Using SSL / TLS

When connecting with SSL/TLS the MQTT-broker has to use a valid certificate that is trusted via the chain of trust of the Android device or provide a custom Java SocketFactory. Currently I am not aware of any public MQTT broker that can be used to test a SSL/TLS connection without a custom SocketFactory, hopefully this will change in the near feature with Let’s Encrypt in place.

IoT Eclipse provides an MQTT Sandbox running MQTT encrypted on and supports TLS 1.0, 1.1 and 1.2. Android on the other hand uses a cryptography API library called BouncyCastle. To generate a BouncyCastle keystore (BKS) on a development machine the BounceCastleProvider class is required in the JAVA-Classpath. The JAR containing the class can be downloaded here. To generate the BKS the JDK keytool can be used with the following parameters:

The command assumes that you saved the BouncyCastle JAR and the into the current directory. It will generate a BouncyCastle Keystore names with the password set to eclipse-password.

To actually use the keystore, create a folder named “assets” in the “src/main” directory of you app and copy file into it. The following example will create a secure MQTT connection to the Eclipse test broker:

The example uses the utility function getSSLSocketFactory of the MqttAndroidClient to create a customSocketFactory from the BKS keystore input stream.

Full example application

The Eclipse Paho project provides a very detailed example application that demonstrates the capabilities of the Paho Android Service. A packaged application is available at Paho Android Sample. The APK is based on the current development branch in the Eclipse repository. To clone the entire GIT repository use the following command:

The Android sample application source is located in folder, that can be opened with Android Studio.

发表在 Linux | 留下评论

给Android Studio设置代理


我们都知道Android Studio是基于JetBrains公司的IDEA开发的,而我们写的每一个程序又都是由Gradle构建的,Gradle集合了Ant和Maven的优点,又解决了他们的缺点,但是它有一个特点还是值得我们注意的.我们每一次点击这个按钮来执行我们的程序时,都会先调用这个来进行构建,这个和Eclipse上还是不一样的,因为Gradle构建的时候要联网,但是联网就联网呗,偏偏还要连接到墙外面的网络,我当初刚开始折腾Android开发的时候可被它给坑苦了,现在想一想真是蛋疼啊,信心满满的装好了高大上的Android Studio,但是由于对它不够了解,且没有深刻理解付费科学上网的重要性,时常出现Gradle Sync Failed的错误,弄得我在Ubuntu和Windows上来回折腾了好几回,一直以为是自己的系统有问题,直到后来(我终于学会了如何去爱大笑).这真的是一个大坑,设想一下,如果我当初稍微不坚定一点,那么可能就跟Android开发Say GoodBye了.所以才有了写下这篇博客的念头,希望这之后的新人们能少踩一些坑(诶,好像我到现在也只是一个新人啊).

作为一个天朝的Android程序员,如果要是不会科学上网的话,那是不是有点太逊了.先说说我吧.第一次跳出墙是刚上大二的时候,偶然间听说了一个叫做Go Agent的开源软件,能免费FQ,所以我在折腾了两个多小时之后终于体会了一把什么叫外面的世界,当时还截了几张YouTube和FaceBook的图发在QQ空间上(后来觉得比较二逼就删掉了),当时还真的是挺兴奋的.后来知道了Go Agent是由Python语言编写的,并且很多人似乎对这门语言很推崇,我就特意去图书馆借了本Python核心编程翻了翻.算是对Go Agent的致敬吧.至于如何使用Go Agent我在这里就不介绍了,大家有兴趣的话可以找一篇帖子试一下.

现在已经不用GoAgent,因为最近GFW屏蔽的比较严重了,Go Agent十分的不稳定,总是需要更换IP List,所以转战到ShadowSocks了.中文名叫做影梭,就是它.


先打开我们的Android Studio,点击工具栏的file下的settings,如下图



默认情况下,No Proxy是被选中的,意思是不需要设置代理.如果你用的是ShadowSocks代理的话则可以按照下面的5 6 7 8四步来做,如下图:


  • Manual proxy configuration翻译过来是人工设置代理的意思.
  • ShadowSocks是SOCKS代理方式
  • 1080是ShadowSocks默认的端口号
这时候如果你的ShadowSocks是能正常工作的话,那么就可以实现Android Studio上网了.测试一下,点击工具栏的Help下的Check for Update选项,如果没有提示不能联网或者提示你更新Studio的话,就说明你成功了少年.
发表在 android | 留下评论

Android ConstraintLayout详解


1. Overview

In this codelab, you’ll learn about ConstraintLayout—a new type of layout available in the Android Support repository built on top of a flexible constraint system. By the end of this codelab, you’ll be able to play with the layout editor in Android Studio and build a relatively complex layout.

What you’ll learn

  • The Constraint System used by the new layout manager.
  • Creating constraints to build flexible and efficient layouts.
  • The various features of the new layout editor.

What you’ll need

2. Get the sample code

To download the sample code, you can either:


…or clone the GitHub repository from the command line by using the following command:

$ git clone

8. Using Autoconnect to create constraints

Autoconnect, as the name suggests, automatically creates connections between widgets. It’s important to understand that the Autoconnect feature tries to create connections to the neighboring widgets.

Before we get started with this section, ensure that:

  1. Open res/layout/activity_main_autoconnect.xml from the Project pane. Ensure that you select the “Design” tab.
  2. Autoconnect is enabled

Next we select the ImageView and center it in the layout by dragging it until the guidelines are shown. A couple of seconds after it is centered, autoconnect kicks in and creates constraints with the top, left, bottom and right of the container, as shown in the animation below.

Here we have a single ImageView on the layout and we see how Autoconnect creates the constraints.

Here are the steps for the next part of this section. For guidance, the animation above shows the steps used below:

  1. Align the ImageView to be placed at the top and use the Inspector (AnySize) to ensure that it expands to fill the width of the parent.
  2. Place two buttons at the bottom right corner of the layout. Use the Inspector pane to change the text attribute of the rightmost button to @string/upload and the one to the left of it to @string/discard.
  3. Drag a TextView and a Plain Text from the palette and place them on the layout.
  4. Adjust the TextView and Plain Text field to be 48dp apart. In a few seconds, Autoconnect creates the constraints to the widgets.
  5. Similarly select the upload button and place it close to our right margin and we let Autoconnect do the rest.
  6. Lastly place the discard button 32dp away from the upload button.

As an exercise, also move the TextView 48dp below the ImageView. To do this select the TextView and move until it’s 48dp below the ImageView.

It’s important to understand that Autoconnect only creates constraints for the widget being currently moved.

Autoconnect aids you by connecting to the nearest widgets which is helpful in many situations. There are cases where Autoconnect does not achieve the desired behavior, and developers should either use manual constraints or Inference to build their ConstraintLayout. Inference will be discussed in the next step of the codelab.

9. Using Inference to create constraints

The Inference engine aids developers by creating constraints among elements added in the layout. The constraints created by Inference depend on the types of elements added to the layout and their sizes.


For this step, we start with the layout/activity_main_inference.xml layout. Open the layout file in the Design view. By default, the layout in this file defines the following:

  • ImageViews for the @drawable/singapore and @drawable/ic_star. The ic_star image has already been constrained to have a vertical bias at 81%. You can view the vertical bias of the ImageView containingic_star by selecting it and checking the Inspector as discussed before.
  • The large ImageView’s bottom anchor (@drawable/singapore) is constrained to the ic_star ImageView’s bottom anchor with a margin of 16dp.
  • In addition to the ImageView, there are TextViews for Camera, Settings, and the subtitle for the ImageView.

What you’ll learn

  • Expanding a view horizontally and vertically using actions on the menu.
  • Using the Inference button to aid in creating constraints using inference.

Understand the UI Builder icon actions

Since we’ll be using some of these options, this is a good time to look at the actions available on the UI Builder.

Delete all constraints. This is helpful when you want to redo all the constraints in your layout in a different way.

Create constraints using inference. The inference engine tries to find and create optimal connections based on various factors such as the positions of the widgets and their size.

Expands the widget horizontally to satisfy constraints.

Expand the widget vertically to satisfy constraints.

Adding a TextView that occupies available space

Our goal is to add a TextView for the description of the image. We already have a@string/singapore_description which spans multiple lines.

  1. First, drag a TextView from the palette and place it below the settings text view.
  2. Use the action to expand the view horizontally to match guidelines.
  3. Use the action to expand vertically to fill available vertical space.

Using the Inference action

Now that you have the TextView in the layout, you are ready to see Inference in action.

Click the infer constraintsaction to create constraints using Inference.

The inference engine creates constraints among all the views in the layout. Your final layout should look like the following:

Once the constraints are created, you can modify the “virtual device to render with” by clicking on the button at the top left of the UI Builder. Choose a different device such as Nexus 6P or Nexus 9 to see that the layout renders correctly.

You’ve now seen the entire spectrum of using the constraint system: creating manual constraints, constraints using auto-connect, and constraints using the Inference engine.

Auto-connect and Inference aid you by having the layout engine figure out how to create constraints for various elements of your UI. You are then free to further modify the constraints created either by Auto-connect or the Inference engine as you see fit.

What we’ve covered

  • Creating Manual constraints
  • Creating constraints using Autoconnect.
  • Creating constraints using Inference.
发表在 android | 留下评论

AndroidStudioでアプリをビルドしたときに「Plugin is too old, please update to a more recent version」エラーが出た時の対処法



Error:(21, 0) Plugin is too old, please update to a more recent version, or set ANDROID_DAILY_OVERRIDE environment variable to "41b72d353033bfb5aa4d6a98088a908dcae15ef9"


1 . ターミナルで、以下のコマンドを実行し環境変数を登録する
(OS Xアプリケーションに環境変数を渡すには、launchctlコマンドのsetenvオプションで設定します。アプリケーションの再起動後から設定が反映されます。)

$ launchctl setenv ANDROID_DAILY_OVERRIDE 41b72d353033bfb5aa4d6a98088a908dcae15ef9

2 . AndroidStudioを起動して、アプリをビルドする。


发表在 Linux | 留下评论