2013年(34)
分类: Android平台
2013-12-16 16:47:29
1.消息推送机制 服务器器端需要变被动为主动,通知客户一些开发商认为重要的信息,无论应用程序是否正在运行或者关闭。 我想到了一句话:don’t call me,i will call you! qq今天在右下角弹出了一个对话框:”奥巴马宣布本拉登挂了…”,正是如此。 自作聪明,就会带点小聪明,有人喜欢就有人讨厌。 2.独立进程 无论程序是否正在运行,我们都要能通知到客户,我们需要一个独立进程的后台服务。 我们需要一个独立进程的后台服务。 在androidmanifest.xml中注册service时,有一个androidrocess属性,如果这个属性以”.”开头,则为此服务开启一个 全局的独立进程,如果以”:”开头则为此服务开启一个为此应用私有的独立进程。举个具体的例子吧,我们新建了一个 application,创建了主进程com.cnblogs.tianxia,那么: 1 2 3 4 5 我们没必要建立一个全局的,本文选择第二种方案,创建一个当前应用私有的独立进程。 3.通知用户和点击查看 package com.alnton.PushMsgDemo.service; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; import android.os.IBinder; import com.alnton.PushMsgDemo.ui.MsgActivity; import com.alnton.PushMsgDemo.ui.R; /** * <通知用户和点击查看的消息推送服务> * 王乾州 */ public class messageservice extends Service { /** * 获取消息线程 */ private messagethread messagethread; /** * 点击查看 */ private Intent messageintent; private PendingIntent messagependingintent; /** * 通知栏消息 */ private int messagenotificationid = 1000; /** * 通知 */ private Notification messagenotification; /** * 通知管理 */ private NotificationManager messagenotificatiomanager; @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startid) { /* 初始化通知 */ messagenotification = new Notification(); messagenotificatiomanager = (NotificationManager)this.getSystemService(android.content.Context.NOTIFICATION_SERVICE); /* 设置通知栏的图标 */ messagenotification.icon = R.drawable.ic_launcher; /* 设置通知栏的内容 */ messagenotification.tickerText = “新消息”; /* 发送通知的时间戳 */ messagenotification.when = System.currentTimeMillis(); /* 设置来通知时候的声音 */ messagenotification.defaults = Notification.DEFAULT_SOUND; // audioStreamType的值必须AudioManager中的值,代表着响铃的模式 messagenotification.audioStreamType = android.media.AudioManager.ADJUST_LOWER; //下边的两个方式可以添加音乐 //notification.sound = Uri.parse(“file:///sdcard/notification/ringer.mp3″); //notification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, “6″); /* 开启线程进行请求消息 */ messagethread = new messagethread(); messagethread.isrunning = true; messagethread.start(); return super.onStartCommand(intent, flags, startid); } /** * 从服务器端获取消息 */ class messagethread extends Thread { /* 线程运行状态 */ public boolean isrunning = true; public void run() { while (isrunning) { try { /* 休息10分钟 */ Thread.sleep(5000); /* 获取服务器消息 */ String servermessage = getservermessage(); if (null != servermessage && !”".equals(servermessage)) { /* 更新通知栏 */ messagenotification.setLatestEventInfo(messageservice.this, “新消息”, servermessage, messagependingintent); messageintent = new Intent(messageservice.this, MsgActivity.class); messageintent.putExtra(“msg”, servermessage); messagependingintent = PendingIntent.getActivity(messageservice.this, 0, messageintent, PendingIntent.FLAG_UPDATE_CURRENT); messagenotificatiomanager.notify(messagenotificationid, messagenotification); /* 每次通知完,通知id递增一下,避免消息覆盖掉 */ messagenotificationid++; } } catch (Exception e) { e.printStackTrace(); } } } } /** * 这里以此方法为服务器demo,仅作示例 * 返回服务器要推送的消息,否则如果为空的话,不推送 */ public String getservermessage() { return “服务器返回的数据”; } } 运行一下: 4.停止服务 view sourceprint?1 stopservice(new intent(myactivity.this,messageservice.class)); 2 setmessagepush(false);//设置配置文件或数据库中flag为false 运行一下,停止服务后,却出乎意料的并没有停下来,怎么回事?是不是代码写错了? 代码没有错,错在我们停止了服务,却没有停止进程,退出线程。 5.退出线程 实践证明,thread的stop()方法并不可靠。但是我们有其他的办法。 在代码面前,程序员就是上帝。 退出线程有两种方法。 第一种方法,强制退出。 view sourceprint?1 //杀死该线程所在的进程,自然就退出了 2 system.exit(0); 第二种方法,设置isrunning为false。 view sourceprint?1 //前面说到了isrunning这个标志,设置为false后,线程的执行就从while循环中跳出来了,然后自然结束 掉了 2 messagethread.isrunning = false; 综合一下,我们在messageservice中重载ondestroy()方法如下: view sourceprint?1 @override 2 public void ondestroy() { 3 system.exit(0); 4 //或者,二选一,推荐使用system.exit(0),这样进程退出的更干净 5 //messagethread.isrunning = false; 6 super.ondestroy(); 7 } |