安卓服务service全解,生命周期,前台服务、后台服务,启动注销、绑定解绑,注册

来源:互联网 发布:dnf本地策略优化 编辑:程序博客网 时间:2024/05/18 01:44

全栈工程师开发手册 (作者:栾鹏)

python教程全解

定义服务(服务的生命周期)

这里写图片描述

调用context.startService()时依次执行 ->onCreate()- >onStartCommand()->Service running

调用context.stopService()时依次执行 ->onDestroy()

调用context.bindService()时依次执行->onCreate()->onBind()->Service running

调用context.onUnbind()时依次执行 -> onDestroy()

当绑定service和所有客户端解除绑定之后,Android系统将会销毁它,(除非它同时被onStartCommand()方法开启)。

因此,如果你的service是一个纯粹的绑定service,那么你不需要管理它的生命周期。

然而,如果你选择实现onStartCommand()回调方法,那么你必须显式地停止service,因为service此时被看做是开启的。

这种情况下,service会一直运行到它自己调用 stopSelf()或另一个组件调用stopService(),不论它是否和客户端绑定。

另外,如果你的service被开启并且接受绑定,那么当系统调用你的 onUnbind()方法时,如果你想要在下次客户端绑定的时候接受一个onRebind()的调用(而不是调用 onBind()),你可以选择在 onUnbind()中返回true。

onRebind()的返回值为void,但是客户端仍然在它的 onServiceConnected()回调方法中得到 IBinder 对象。

下图展示了这种service(被开启,还允许绑定)的生命周期:
这里写图片描述

代码示例:

代码中设计服务的生命周期,服务设置为前台服务和后台服务。

package com.lp.app.service;import com.lp.app.Activity1;import com.lp.app.R;import android.app.Notification;import android.app.PendingIntent;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.util.Log;//服务的生命周期public class Service1 extends Service{      public final static String action_name = "com.lp.action.service1";      public final static String key1 = "key1";      public final static String key2 = "key2";       //当服务被创建时,执行oncreat函数      @Override      public void onCreate() {          Log.v("服务生命周期", "服务第一次被启动");          pausePlayback();   //将服务放置在后台。默认服务就是后台服务。前台服务是一个通知栏          startPlayback("显示标题","显示文本");   //打开一个通知栏,点击通知,可以将服务移动至前台      }      //onStartCommand为service的重新启动函数      @Override      public int onStartCommand(Intent intent, int flags, int startId) {        //startBackgroundTask(intent, startId);   //将服务设置到后台运行        //START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,重新启动后参数Intent将为null。        //START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。        //START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将原来Intent的值传入。        //START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。        //参数flags可以用来确定service的启动方式。START_FLAG_REDELIVERY表示Intent参数是由系统运行时在通过stopSelf显式停止service之前终止它而重新传递的。                                                //FLAF_RETRY表示service已经在异常终止后重新启动,如果service之前被设为START_STICKY,则会传入这个标志        Log.v("服务生命周期", "服务被其他窗口通过startService()启动");        return Service.START_STICKY;       }        public class MyBinder extends Binder {            Service1 getService() {              return Service1.this;            }          }        private final IBinder binder = new MyBinder();        @Override        public IBinder onBind(Intent intent) {            // TODO 自动生成的方法存根            Log.v("服务生命周期", "一个客户端正在通过bindService()函数绑定到本服务");            return binder;        }        @Override        public void onRebind(Intent intent)        {            //在onUnbind()函数已经被调用过后执行            Log.v("服务生命周期", "一个客户端正在通过bindService()函数绑定到当前服务");        }        @Override        public boolean onUnbind(Intent intent)        {            Log.v("服务生命周期", "所有客户端已经通过unbindService()函数脱离绑定");            return true;  //返回允许绑定        }        @Override        public void onStart(Intent intent,int startId){            Log.v("服务生命周期", "服务启动");            super.onStart(intent, startId);        }        @Override        public void onDestroy(){            Log.v("服务生命周期", "服务销毁");            super.onDestroy();        }      //将一个service移动至前台      //(前台服务:会在通知一栏显示 ONGOING 的 Notification。当服务被终止的时候,通知一栏的 Notification 也会消失,这样对于用户有一定的通知作用)      //前台服务具有较高的优先级,能在内存不足时,不被杀死      private void startPlayback(String contenttitle, String contenttext) {        int NOTIFICATION_ID = 1;        //创建一个当单击通知时将打开主activity的intent        Intent intent = new Intent(this, Activity1.class);        PendingIntent pi = PendingIntent.getActivity(this, 1, intent, 0);        //设置Notification UI参数        Notification notification = new Notification(R.drawable.icon,"启动app窗口", System.currentTimeMillis());        notification.setLatestEventInfo(this, contenttitle, contenttext, pi);        //设置notification为持续显示        notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT;        //将service移到前台。        startForeground(NOTIFICATION_ID, notification);      }      //将service移动到后台      public void pausePlayback() {        //移动到后台并移除Notification        stopForeground(true);      }}

在manifest文件中注册服务

这里我们hi演示显式启动服务和隐式启动服务。所有这里处理设置服务的名称,还设置了触发条件

<!-- service注册服务,其中permission表示要想外部应用程序使用这个服务,必须要包含的自定义权限(只是个名称) --><service     android:name="com.lp.app.service.Service1"    android:permission="com.lp.my_service1_permission">    <intent-filter>        <action android:name="com.lp.action.service1"/>        <category android:name="android.intent.category.DEFAULT"/>    </intent-filter></service> 

显式的启动和终止服务

  Intent serviceIntent=null;  //显示启动一个服务  private void explicitStart() {    serviceIntent = new Intent(this, Service1.class);    startService(serviceIntent);  }  //显式终止一个服务  private void explicitStop() {      if(serviceIntent!=null)            stopService(serviceIntent);  }

隐式的启动和终止服务

隐式启动,相当于把自定义服务注册为系统服务,再以启动系统服务的方式启动自定义服务。

这种方式的和显式的启动和停止服务不同,而是通过intent触发指定名称的事件。而这个事件又触发了注册在manifest文件中的service,所以需要在manifest文件中注册服务时,设定触发源

  //隐式的启动一个Service。相当于把自定义服务注册为系统服务,再以启动系统服务的方式启动自定义服务  private void implicitStart() {    Intent intent = new Intent(Service1.action_name);   //在注册服务是设置了intent-filter,所以启动这个,可以启动对应的服务    intent.putExtra(Service1.key1, "value1");     intent.putExtra(Service1.key2, "value2");     startService(intent);  }  //隐式终止一个服务  private void implicitStop() {      Intent intent = new Intent(Service1.action_name);      stopService(intent);   }

绑定和解除绑定

 //为Service绑定创建一个service连接  //service的引用  private Service1 serviceRef;  //处理service和 activity之间的连接  private ServiceConnection mConnection = new ServiceConnection() {       //当建立连接时调用此函数       public void onServiceConnected(ComponentName className, IBinder service) {         serviceRef = ((Service1.MyBinder)service).getService();         Log.v("服务绑定客户端", "服务绑定建立连接");       }       //当service意外断开时执行       public void onServiceDisconnected(ComponentName className) {         serviceRef = null;         Log.v("服务绑定客户端", "服务绑定断开连接");       }  };  Intent bindIntent=null;  //绑定一个service和activity  private void bindToService() {    bindIntent = new Intent(this, Service1.class);    bindService(bindIntent, mConnection, Context.BIND_AUTO_CREATE);    //BIND_AUTO_CREATE表示收到绑定请求的时候,如果服务尚未创建,则即刻创建,在系统内存不足需要先摧毁优先级组件来释放内存,且只有驻留该服务的进程成为被摧毁对象时,服务才被摧毁    //BIND_DEBUG_UNBIND通常用于调试场景中判断绑定的服务是否正确,但容易引起内存泄漏,因此非调试目的的时候不建议使用    //BIND_NOT_FOREGROUND表示系统将阻止驻留该服务的进程具有前台优先级,仅在后台运行,该标志位位于Froyo中引入  }  //解除一个绑定  private void unbindToService() {    if (bindIntent!=null) {        unbindService(mConnection);    }  }
阅读全文
0 0
原创粉丝点击