【四大组件-Service的使用注意事项】

  1. 多次调用 startService()则只会重复调用 onStartCommand()

多次调用 bindService(…) ,只会重复调用 onReBind() 。 除非Service已经 unBind 了,否则即使多次重复调用 bindService() ,也不会导致 onBind()方法被调用。

若 onBind()没有被调用则 ,ServiceConnection 的回调方法 onServiceConnected(..) 就不会被调用。

因此如果需要在 ServiceConnection 的回调方法 onServiceConnected(…) 中做一些重要的业务逻辑时,则不能期望通过调用 bindService() 来实现 onServiceConnected(…)方法一定被调用。

  1. 需要注意一个问题 :

    当Activity退出的时候,Sercvice并不会停止,此时我们可以再进入Activity重新绑定,当这时候 Service就会调用onRebind()方法,但是调用onRebind()方法的前提是先前的onUnbind()方法执行成功,但是使用 super.onUnbind(intent)是执行不成功的,

    这时候我们要手动的使其返回true,再次绑定时Rebind()就会执行。否则,如果退出时不显示的指定onUnbind()为成功的话(为false),那么重新启动此Activity来绑定服务时,Service的onBind()方法和onReBind都不会执行,但是ServiceConnection方法确一定会回调了。这说明在Service中的onBind()方法不同于 onStart()方法不能被重复调用。

    源码如下:

      /**
         * Called when all clients have disconnected from a particular interface
         * published by the service.  The default implementation does nothing and
         * returns false.
         * 
         * @param intent The Intent that was used to bind to this service,
         * as given to {@link android.content.Context#bindService
         * Context.bindService}.  Note that any extras that were included with
         * the Intent at that point will <em>not</em> be seen here.
         * 
         * @return Return true if you would like to have the service's
         * {@link #onRebind} method later called when new clients bind to it.
         */
        public boolean onUnbind(Intent intent) {
          
          
            return false; //默认返回 FALSE ,因此如果想要 onRebind()可以被调用,则子类需要重写此方法。
        }
    
  2. 建议使用 stopSelf( int ) 确保服务停止于最近的启动请求

    如果服务同时处理多个 onStartCommand() 请求,则不应该在处理第一个启动请求后停止服务,有可能你已经接收新的启动请求(第一个请求结束时停止服务会终止第二个请求)。为了避免这个问题,可以使用 stopSelf( int ) 确保服务停止于最近的启动请求。也就是,在调用 stopSelf( int ) 时,传递与停止请求的 ID 对应的启动请求 ID (传递给 onStartCommand() 的 startId )。然后,在调用 stopSelf( int ) 之前服务收到了新的请求,ID 不匹配,服务也就不会停止。
    注意: 为了避免浪费系统资源和小号电池电量,应用必须在工作完成后停止其服务。如有必要,其他组件可以通过调用 stopService 来停止服务,即使为服务启用了绑定,一旦服务受到对 onStartCommand 的调用, 始终需要亲自停止服务。

  3. 【推荐】 总是使用 显式 Intent 启动或者 绑定 Service ,且不要为服务声明 Intent Filter
    这样可以保证应用程序的安全性。如果确实需要使用隐式调用,则可以为 Service设置 Intent - Filter,并从tent中设置排除相关的组件名称,但必须搭配使用intent.setPackage()方法来设置Intent的指定包名(只允许当前应用程序包名的Intent才能开启此Service)。

  4. 【推荐】 Service 需要以多线程来并发处理个启动请求,建议使用 IntentService 来处理耗时操作,这样可以避免许多复杂的设置。

    例: 小米推送中 继承自BroadcastReceiver 的 PushMessageReceiver 的 onReceive 方法,每次收到广播就会 start 一个叫 MessageHandleService 的Service,而这个MessageHandleService 实际上就是一个 IntentService 。

猜你喜欢

转载自blog.csdn.net/UserFrank/article/details/129204103
今日推荐