Android 之 Service

两种启动方式
bindService、startService两种
startService这种service可以无限地运行下去,必须调用stopSelf()方法或者其他组件调用stopService()方法来停止它。当service被停止时,系统会销毁它。
bindService:被绑定的service是当其他组件(一个客户)调用bindService()来创建的。
客户可以通过一个IBinder接口和service进行通信。
客户可以通过 unbindService()方法来关闭这种连接。
一个service可以同时和多个客户绑定,当多个客户都解除绑定之后,系统会销毁service。生命周期随它绑定的组件而定 生命周期
在下图中,左侧的为startService方式启动Service的生命周 期,右侧为bindService方式启动Service时的生命周期 两种生命周期 如果service是被开启的,那么它的活动生命周期和整个生命周期一同结束。 如果service是被绑定的,它们它的活动生命周期是在onUnbind()方法返回后结束。

service和Thread区别?

Thread 是程序执行的最小单元,它是分配CPU的基本单位。可以用 Thread 来执行一些异步的操作。
Service是一个专门在后台处理长时间任务的Android组件,它没有UI
Service 是android的一种机制,当它运行的时候如果是Local Service,那么对应的 Service 是运行在主进程的 main 线程上的。如:onCreate,onStart 这些函数在被系统调用的时候都是在主进程的 main 线程上运行的。如果是Remote Service,那么对应的 Service 则是运行在独立进程的 main 线程上

Service中可以弹Toast吗?

这个问题其实就是问一下Service是执行在UI线程中吗?类似的问题还有 “Service的onCreate回调函数可以做耗时的操作吗?” “Service 是否在 main thread 中执行” “Service 和 Activity 在同一个线程吗?” 我们要牢记一句真理“默认情况下四大组件都是在UI线程中执行的”,Service 本身就是 Context 的子类,我们可以获取到Context对象,所以Service中当然可以弹Toast,同理,Service的onCreate回调函数不可以做耗时的操作; 特殊情况 ,可以在清单文件配置 service 执行所在的进程 ,让 service 在另外的进程中执行

<service  
android:name="com.baidu.location.f"  
android:enabled="true"  
android:process=":remote" >  
</service>  

*如何保证Service在后台不被kill *

重写onStartCommand返回STARTSTICKY,STARTSTICKY是service被kill掉后自动重写创建
在onDestroy里启动service监听系统广播,如果还能监听到系统广播就说明服务没有被Kill
Application加上Persistent属性,让应用变成随系统关闭而关闭。
提升Service优先级:设置android:priority = “1000” 放一个像素在桌面
Android中的进程是托管的,当系统进程空间紧张的时候,会依照优先级自动进行进程的回收 当service运行在低内存的环境时,将会kill掉一些存在的进程。因此进程的优先级将会很重要,可以使用startForeground 将service放到前台状态。这样在低内存时被kill的几率会低一些。
IntentService与Service的区别?

Service 也不是专门一条新线程,因此不应该在 Service 中直接处理耗时的 任务;
Service 不会专门启动一条单独的进程,Service 与它所在应用位于同一个进 程中;
IntentService 是 Service 的子类,是一个异步的,会自动停止的服务,很好解决了传统的Service中处理完耗时操作忘记停止并销毁Service的问题
IntentService 会创建独立的worker线程来处理所有的Intent请求;
IntentService不会阻塞UI线程,而普通Serveice会导致ANR异常
Intentservice若未执行完成上一次的任务,将不会新开一个线程,是等待之前的任务完成后,再执行新的任务,等任务完成后再次调用stopSelf()
正在运行的 IntentService 的程序相比起纯粹的后台程序更不容易被系统杀死,该程序的优先级是介于前台程序与纯后台程序之间的

Service是否正在运行

public static boolean isServiceRunning(Context mContext,String className) {

           boolean isRunning = false;
           ActivityManager activityManager = (ActivityManager)
           mContext.getSystemService(Context.ACTIVITY_SERVICE); 
           List<ActivityManager.RunningServiceInfo> serviceList 
                      = activityManager.getRunningServices(30);

           if (!(serviceList.size()>0)) {
               return false;
           }

           for (int i=0; i<serviceList.size(); i++) {
               if (serviceList.get(i).service.getClassName().equals(className) == true) {
                   isRunning = true;
                   break;
               }
           }
           return isRunning;
       }

张鹏宇

继续阅读此作者的更多文章