您的当前位置:首页正文

关于Service的知识点(上)

来源:图艺博知识网

服务的生命周期

服务的分类

  • 远程服务---->运行在不同的进程中的服务。
    通过对android:process=":service"属性指定不同进程。
  • 本地服务---->运行在同一进程中的服务。

按调用方式分类。

  • startService启动,即使启动它的应用组建销毁了,服务也会存在。不进行通信。停止服务使用stopService(不管你调用了多少次startService);

  • bindService调用启动,当启动它的组建销毁,服务也会跟着销毁。可以进行通信。停止服务使用unbindService;

  • startService、bindService 同时启动,停止服务应同时使用stopService与unbindService
    下面来写一个服务,在它们的生命周期回调方法中分别打印日志。代码如下:

      public class MyService1 extends Service {
          public static final String TAG = MyService1.class.getSimpleName();
     
          @Override
          public void onCreate() {
              super.onCreate();
              Log.e(TAG, TAG + "-->onCreate()");
          }
      
          @Nullable
          @Override
          public IBinder onBind(Intent intent) {
              Log.e(TAG, TAG + "-->onBind()");
              return null;
          }
      
          @Override
          public int onStartCommand(Intent intent, int flags, int startId) {
              Log.e(TAG, TAG + "-->onStartCommand()");
              return super.onStartCommand(intent, flags, startId);
          }
      
          @Override
          public void onDestroy() {
              super.onDestroy();
              Log.e(TAG, TAG + "-->onDestroy()");
          }
      
          @Override
          public boolean onUnbind(Intent intent) {
              Log.e(TAG, TAG + "-->onUnbind()");
              return super.onUnbind(intent);
          }
      }
    

别忘了在清单配置文件里配置。<service android:name=".services.MyService1"></service>接着我们来看一下startService,startService、bindService
启动的生命周期调用。其中MainActivity的布局文件代码:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 
        
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical"
        tools:context="com.example.serviceexample.MainActivity">
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:onClick="start"
            android:text="start启动服务" />
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:onClick="stop"
            android:text="stop停止服务" />
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:onClick="bind"
            android:text="bind启动服务" />
    
        <Button
            android:onClick="unbind"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:text="unbind停止服务" />
    
    
    </LinearLayout>

startService

public void start(View view) {
    Intent intent = new Intent(this, MyService1.class);
    startService(intent);
}

public void stop(View view) {
    Intent intent = new Intent(this, MyService1.class);
    stopService(intent);
}

点击start启动服务,点击stop停止服务。就看一下它的生命周期。onCreate()-->onStartCommand()-->onDestroy();

多次点击start启动服务,会是什么现象?



你会发现就调用了一次onCreate(),这是由于onCreate()方法只会在Service第一次被创建的时候调用,如果当前Service已经被创建过了,
不管怎样调用startService()方法,onCreate()方法都不会再执行,而onStartCommand()不是。

bindService

public class MainActivity extends AppCompatActivity {
    private ServiceConnection connection;//服务连接
    public static final String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //实现连接的回调
        connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                Log.e(TAG, "onServiceConnected()+");
            }

            @Override
            public void onServiceDisconnected(ComponentName componentName) {

            }
        };
    }


    public void bind(View view) {
        Intent intent = new Intent(this, MyService1.class);
        bindService(intent, connection, BIND_AUTO_CREATE);
    }

    public void unbind(View view) {
        unbindService(connection);
    }
    
    
}

这里bindService需要传三个参数,第1个参数中将Intent传递给bindService()函数,声明需要启动的Service 第二个参数是前面创建出的ServiceConnection的实例,
不能为空,第3个参数Context.BIND_AUTO_CREATE表明只要绑定存在,就自动建立Service。
点击bind启动服务,点击unbind停止服务。就看一下它的生命周期。onCreate()-->onBind()-->onUnbind()-->onDestroy();


服务是运行在主线程中的,不信你可以分别在MainActivity和MyService1的onCreate()方法中打印Log.e(TAG, TAG +"Thread id: "+ Thread.currentThread().getId());它们的线程ID是一样的。

关于服务的onStartCommand()方法。

onStartCommand()替换了onStart()方法,这里主要介绍一下onStartCommand()方法返回值的含义,它有四个返回值:START_STICKY、START_NOT_STICKY、START_REDELIVER_INTENT、START_STICKY_COMPATIBILITY。

  • START_STICKY
    如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。
    如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。

  • START_NOT_STICKY
    “非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。

  • START_REDELIVER_INTENT
    重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。

  • START_STICKY_COMPATIBILITY
    START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

Top