前言:
在我司项目1.0版本的时候消息是使用的环信、用了之后发现各种bug,各种机型不支持导致app崩溃,于是在2.0版本果断去掉环信,使用了公众号用的那套消息系统(老大自己写的)并做了扩展升级。搞了近半个月终于是搞完了,项目也顺利上线......
你无法想象,检测未读消息/新消息我写了个线程,每隔30s去请求一个,好low的,app退出后你就拜拜了吧,肯定要改啊!用什么?service呗,于是开始service之旅...
废话连篇,开始我们的Service之旅吧!
1.我们要知道什么是Service?
A Service is an application component representing either an application's desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use. Each service class must have a corresponding
declaration in its package'sAndroidManifest.xml
. Services can be started with Context.startService()
and Context.bindService()
.
呵呵,你看得懂?
废话...
简单解释下就是:Service是一个应用程序组件,它能够在后台执行一些耗时较长的操作,并且不提供用户界面。服务能被其它应用程序的组件启动,即使用户切换到另外的应用时还能保持后台运行。此外,应用程序组件还能与服务绑定,并与服务进行交互,甚至能进行进程间通信(IPC)。 比如,服务可以处理网络传输、音乐播放、执行文件I/O、或者与content provider进行交互,所有这些都是后台进行的(抱歉,我抄的...)
附:Service官方介绍:传送门
Android中文API:传送门
2.Service生命周期
一会我们通过代码看结果,先了解...
3.Service基本类型(启动方式):
Started :通过应用程序组件(例如Activity)调用startService()启动服务:StartService(intent)系统通通过传入的intent搜索相关符合intent的Service,
依次执行其相关生命周期,service一旦启动就会一直在后台运行,直到调用stopService或stopSelf停止服务。
注:public void onStart(Intent intent, int startId) {}已过时,在2.0之后引入public int onStartCommand(Intent intent, int flags, int startId) {},flags,Service启动函数,后面介绍。
Bind:通过bindService()绑定服务,该提供了一个客户端/服务器接口,允许组建与服务进行交互、发送请求、返回结果,设置可以利用进程间通信夸进程执行这些操作;多个组件
可以同时与一个服务绑定,通过onUnbind()方法解绑服务,当所有组件解绑后,服务也被销毁。
1). onStartCommand() 返回常量Flag介绍:
@Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i("TAG", "Services onStartCommand"); return START_REDELIVER_INTENT; }
startForeground(int id, Notification notification) Make this service run in the foreground, supplying the ongoing notification to be shown to the user while in this state. |
NotificationCompat.Builder builder = new NotificationCompat.Builder(G.applicationContext); Notification notification = builder.build(); notification.flags = Notification.FLAG_FOREGROUND_SERVICE; startForeground(0, notification); Log.i("Service", "UnreadMessageServices onStartCommand"); return START_STICKY;
public class BootBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Intent unreadCountService = new Intent(context, UnreadCountService.class); Intent checkService = new Intent(context, CheckService.class); context.startService(unreadCountService); context.startService(checkService); Log.v("TAG", "开机自动服务自动启动....."); } }同时需要配置其权限AndroidManifest.xml
android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
android:name=".help.BootBroadcastReceiver" android:permission="android.permission.RECEIVE_BOOT_COMPLETED"> android:name="android.intent.action.BOOT_COMPLETED" /> android:name="android.intent.category.DEFAULT" />
private class CheckBroadCastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("Intent.ACTION_TIME_TICK")) { //检查Service状态 if (isServiceRunning(context, "rain.myapp.help.UnreadCountService") == false) { //重启服务 Intent i = new Intent(context,UnCountService.class); context.startService(i); } } } } /** * 判断服务是否正在运行中 * * @param context Context对象 * @param serviceName Service全名 * @return */ private boolean isServiceRunning(Context context, String serviceName) { if (!TextUtils.isEmpty(serviceName) && context != null) { ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); ArrayListrunningServiceInfoList = (ArrayList ) activityManager.getRunningServices(100); for (Iterator iterator = runningServiceInfoList.iterator(); iterator.hasNext(); ) { ActivityManager.RunningServiceInfo runningServiceInfo = iterator.next(); if (serviceName.equals(runningServiceInfo.service.getClassName().toString())) return true; } } else return false; return false; }