开发部署方法:
1. 下载androidpn的客户端和服务器:地址为:http://sourceforge.net/projects/androidpn/files/
2. 解压服务器端,点击运行,访问:http://127.0.0.1:7070/user.do,就可以看服务器端的管理页面,用这个管理页面,就要向客户端push消息。
3. 把客户端导入到eclipse工程中,修改raw/androidpn.properties文件中的xmppHost的值,如果在模拟器上访问就设置为10.0.2.2(详情请见:http://blog.csdn.net/android_tutor/article/details/4996752),如果是在手机上访问就设置为服务器的ip就行。
讲讲androidpn客户端的写法:
先从最关健的后台Service开始请起:
从类的层次看这个结构比较简单,让其变得复杂的是,其里面有三个线程:主线程,进行Xmpp通信线程,连接出错重试线程。
对上图进行说明:
1. 在NotificationService里创建一个单线程,让其对服务器进行连接,由于使用Xmpp连接服务器要分为三步:连接,注册,登陆。所以用一个栈来保存要执行的Task任务(ConnectTask,RegisterTask,LoginTask),还后再按这个顺序进行执行。
2. 连接Xmpp服务器的线程用的是Executors.newSingleThreadExecutor(),这个本身可以不停的submit任务,那为什么还要自己用一个栈来保存Task了,我的猜测是虽然可以不停的提交任务,但其执行顺序不能保证,哈哈,这个推测可能是错的。
3. 连接线程在连接,注册,登陆的过程中,都有可能出错,都可能会失败,这时我就要有一个重连的机制,在Androidpn里开了另外一个线程来进行重试,其重试不是每次都按多少秒来进行重试,而是有其自己的规则。
- private int waiting() {
- // 重试次数大于20次,其睡眠600秒
- if (waiting > 20) {
- return 600;
- }
- // 重试次数大于13次,睡眠300秒
- if (waiting > 13) {
- return 300;
- }
- // 重试次数小于等于7次,睡眠10秒,大于7次,睡眠60秒
- return waiting <= 7 ? 10 : 60;
- }
4. 在LoginTask里,如果登陆了服务器端,其就会注册一个监听器,用于监听服务器push的数据包(Packet),再通过发送广播的方式来通知要进行显示的程序。
5. 在登陆服务器后,也有可能出错,所以在登陆后,会设置一个ConnectionListener,用于监听连接出错的时候,再合适重连线程,进行重连
6. 在登陆过程中,有一种错误要单独处理,就是账号和密码无效的时候,这个时候其返回的状态码是401,这种情况应该把本地保存的帐号和密码都清掉,再重新进行连接,不然会永远都登陆不上服务器端。
其以上的线程写法不一定是最好的,我们也可以用Hander来进行重试,或者用TimeTask来管理线程也可以。