Android Service详细介绍

       Service 服务是 Android 系统最常用的四大组件之一,在Android系统中,一是简化后台任务的实现,二是实现在同一台设备当中跨进程的远程信息通信。在Android开发中Service也是我们必备的知识,本文对Service知识进行了一些梳理和总结,相信通过本文能让你对Service有更清晰的了解和认识。废话不多说,现在开车啦。

 一、Service的概念

       Service的官方定义:Service(服务)是一个应用程序组件,可以在后台执行长时间运行的操作,不提供用户界面。另一个应用程序组件可以启动一个服务,它将继续在后台运行,即使用户切换到另一个应用程序。另外,一个组件可以绑定到一个服务来与它交互,甚至可以执行进程间通信(IPC)。例如,服务可能处理网络传输、播放音乐、文件I/O或者与内容提供者交互,这些都来自后台。

        这里要说明的是,Service虽然是在后台运行,但是Service默认并不会运行在子线程中,它也不运行在一个独立的进程中,它同样执行在UI主线程中,因此,不要在Service中执行耗时的操作,除非你在Service中创建了子线程来完成耗时操作。

         Service的运行不依赖于任何用户界面,即使程序被切换到后台或者用户打开另一个应用程序,Service仍然能够保持正常运行,这也正是Service的使用场景。当某个应用程序进程被杀掉时,所有依赖于该进程的Service也会停止运行。

二、Service的分类

按运行地点分类:

类别区别 优点缺点  应用
本地服务(Local)该服务依附在主进程上 服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外Local服务因为是在同一进程因此不需要IPC,也不需要AIDL。相应bindService会方便很多。 主进程被Kill后,服务便会终止。 常见的应用如:音乐播放的服务。
远程服务(Remote)该服务是独立的进程 服务为独立的进程,对应进程名格式为所在包名加上你指定的android:process字符串。由于是独立的进程,因此在Activity所在进程被Kill的时候,该服务依然在运行,不受其他进程影响,有利于为多个进程提供服务具有较高的灵活性。 该服务是独立的进程,会占用一定资源,并且使用AIDL进行IPC稍微麻烦一点。 一些提供系统服务的Service,这种Service是常驻的。

其中remote服务还是很少见的,并且一般都是系统服务。 

按运行类型分类:

类别区别应用
前台服务会在通知一栏显示 ONGOING 的 Notification。当服务被终止的时候,通知一栏的 Notification 也会消失,这样对于用户有一定的通知作用。常见的如音乐播放服务。
后台服务默认的服务即为后台服务,即不会在通知一栏显示 ONGOING 的 Notification。当服务被终止的时候,用户是看不到效果的。某些不需要运行或终止提示的服务,如天气更新,一些在后台同步的服务等。

按使用方式分类:

类别区别
startService 启动的服务主要用于启动一个服务执行后台任务,不进行通信。停止服务使用stopService
bindService 启动的服务该方法启动的服务要进行通信。停止服务使用unbindService
startService 同时也 bindService 启动的服务停止服务应同时使用stopService与unbindService

三、Servie的用法

1.新建一个类,继承自Service,如果是startService要重写onStartCommand方法,如果是bindService要实现它的onBind()方法。示例如下:

public class FirstService extends Service {
    private static final String TAG = "FirstService";
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG, "--------->onBind: Thread ID = " + Thread.currentThread().getId());
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "--------->onCreate:Thread ID = " + Thread.currentThread().getId());
    }
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
       Log.e(TAG, "--------->onStartCommand:- startId = " + startId + ", Thread ID = " + Thread.currentThread().getId());
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Log.e(TAG, "--------->onDestroy: Thread ID = " + Thread.currentThread().getId());
        super.onDestroy();
    }
}

2.接着在AndroidManifest.xml中注册Service

<application  
        android:allowBackup="true"  
        android:icon="@mipmap/ic_launcher"  
        android:label="@string/app_name"  
        android:supportsRtl="true"  
        android:theme="@style/AppTheme"> 
        <service android:name=".FirstService">  
        </service>  

    </application>  

3.在Activity或者其他组件中就可以通过startService或者bindService来启动Service。

四、Service生命周期

1.Android官方Service生命周期图:

        

左边的图显示了使用startService()创建服务时的生命周期,右边的图表显示了使用bindService()创建服务时的生命周期。

2. Service 服务的常用方法说明:

方法 说明
void onCreate()当Service被启动时被触发,无论使用Context.startServcie还是Context.bindService启动服务,在Service整个生命周期内只会被触发一次
int onStartCommand(Intent intent, int flags, int startId)当通过Context.startService启动服务时将触发此方法,但当使用 Context.bindService 方法时不会触发此方法,其中参数 intent 是 startCommand 的输入对象,参数 flags 代表 service 的启动方式,参数 startId 当前启动 service 的唯一标式符。返回值决定服务结束后的处理方式,下文将再作详细说明。
void onStart(Intent intent,int startId)2.0旧版本的方法,已被Android抛弃,不推荐使用,默认在onStartCommand 执行中会调用此方法
IBinder onBind(Intent intent)使用 Context.bindService 触发服务时将调用此方法,返回一个IBinder 对象,在远程服务时可用于对 Service 对象进行远程操控
void onRebind(Intent intent)当使用startService启动Service,调用bindService启动Service,且 onUnbind 返回值为 true 时,下次再次调用 Context.bindService 将触发方法
boolean onUnbind(Intent intent)调用 Context.unbindService 触发此方法,默认返回 false, 当返回值 true 后,再次调用 Context.bindService 时将触发 onRebind 方法
void onDestory()分三种情况:1.以Context.startService启动service,调用Context.stopService结束时触发此方法;2.以Context.bindService启动service,以Context.unbindService结束时触发此方法;3.先以Context.startService 启动服务,再用Context.bindService绑定服务,结束时必须先调用Context.unbindService解绑再使用Context.stopService结束service才会触发此方法。

3.详细说下onStartCommand 方法:

由于手机的RAM、内部资源有限,所以很多Service都会因为资源不足而被Kill掉,这时候返回值就决定了Service被Kill后的处理方式,一般 int onStartCommand(intent,flags,startId)的返回值分为以下几种:
START_STICKY
如果service进程被kill掉,系统会尝试重新创建Service,如果在此期间没有任何启动命令被传递到Service,那么参数intent将为NULL。
START_NOT_STICKY
使用这个返回值时,如果在执行完onStartCommand()后,服务被异常kill掉,系统不会自动重启该服务。
START_REDELIVER_INTENT
使用这个返回值时,如果在执行完onStartCommand()后,服务被异常kill掉,系统会自动重启该服务,并将intent的值传入。
START_STICKY_COMPATIBILITY

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

而输入参数flags正是代表此次onStartCommand()方法的启动方式,正常启动时,flags默认为0,被kill后重新启动,参数分为以下两种:
START_FLAG_RETRY
代表service被kill后重新启动,由于上次返回值为START_STICKY,所以参数 intent 为null
START_FLAG_REDELIVERY

代表service被kill后重新启动,由于上次返回值为START_REDELIVER_INTENT,所以带输入参数intent。

4.service生命周期方法详细调用的顺序:

(一)startServie的生命周期方法的调用顺序:

创建FirstService,并在Manifest里注册。然后在Activity里操作,代码如下:

public class FirstService extends Service {
    private static final String TAG = "FirstService";
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG, "--------->onBind: Thread ID = " + Thread.currentThread().getId());
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "--------->onCreate:Thread ID = " + Thread.currentThread().getId());
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
      Log.e(TAG, "--------->onStartCommand:- startId = " + startId + ", Thread ID = " +  Thread.currentThread().getId());
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Log.e(TAG, "--------->onDestroy: Thread ID = " + Thread.currentThread().getId());
        super.onDestroy();
    }

}

在MainActivity中三次startService,之后stopService。

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i(TAG, "Thread ID = " + Thread.currentThread().getId());
        Log.i(TAG, "before StartService");
        //连续启动Service
        Intent intentOne = new Intent(this, FirstService.class);
        startService(intentOne);
        Intent intentTwo = new Intent(this, FirstService.class);
        startService(intentTwo);
        Intent intentThree = new Intent(this, FirstService.class);
        startService(intentThree);
        //停止Service
        Intent intentFour = new Intent(this, FirstService.class);
        stopService(intentFour);
        //再次启动Service
        Intent intentFive = new Intent(this, FirstService.class);
        startService(intentFive);
        Log.i(TAG, "after StartService");
    }

}

打印出的Log如下:

04-27 16:00:19.120 16775-16775/com.jiusi.equiview E/FirstService: --------->onCreate:Thread ID = 1
    --------->onStartCommand:- startId = 1, Thread ID = 1
04-27 16:00:19.130 16775-16775/com.jiusi.equiview E/FirstService: --------->onStartCommand:- startId = 2, Thread ID = 1
    --------->onStartCommand:- startId = 3, Thread ID = 1
    --------->onDestroy: Thread ID = 1
    --------->onCreate:Thread ID = 1
    --------->onStartCommand:- startId = 1, Thread ID = 1

分析:
a. 主线程打印出是1,所有回调方法中打印出的执行线程ID都是1,证明 回调方法都是在主线程中执行的
b. 三次调用startService,只触发一次onCreate回调,触发了三次onStartCommand回调,且startId分别为1,2,3。证明 多次startService不会重复执行onCreate回调,但每次都会执行onStartCommand回调

(二)通过bindService启动Service,

(1)这种方式启动服务的特点:

1. bindService启动的服务和调用者之间是典型的 client-server模式。调用者是client,Service则是server端。Service只有一个,但绑定到Service上面的client可以有一个或很多个。这里所提到的client指的是组件,比如某个Activity。
2.  client可以通过IBinder接口获取Service的实例,从而实现在client端直接调用Service中的方法以实现灵活交互,这在通过startService方法启动中是无法实现的。
3. bindService启动服务的生命周期与其绑定的client息息相关。当client销毁时,client会自动与Service解除绑定。当然,client也可以明确调用unbindService()方法与Service解除绑定。 当没有任何client与Service绑定时,Service就会自行销毁
(2)示例如下:
要想让Service支持bindService调用方式,需要做以下事情:
1.在实现的Service的onBind()方法中返回IBinder类型的实例。
2.onBInd()方法返回的IBinder的实例需要能够返回Service实例本身。通常, 最简单的方法就是在service中创建binder的内部类,加入类似getService()的方法返回Service,这样绑定的client就可以通过getService()方法获得Service实例了。
代码如下:
public class SecondService extends Service {
    private static final String TAG = "SecondService";
    //client 可以通过Binder获取Service实例
    public class MyBinder extends Binder {
        public SecondService getService() {
            return SecondService.this;
        }
    }

    //通过binder实现调用者client与Service之间的通信
    private MyBinder binder = new MyBinder();
  
    @Override
    public void onCreate() {
        Log.e(TAG,"TestTwoService - onCreate - Thread = " + Thread.currentThread().getName());
        super.onCreate();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
   Log.e(TAG,"TestTwoService-onStartCommand-startId="+startId+", Thread = " + Thread.currentThread().getName());
        return START_NOT_STICKY;
    }
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG, "TestTwoService - onBind - Thread = " + Thread.currentThread().getName());
        return binder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e(TAG, "TestTwoService - onUnbind - from = " + intent.getStringExtra("from"));
        return false;
    }
    @Override
    public void onDestroy() {
        Log.e(TAG, "TestTwoService - onDestroy - Thread = " + Thread.currentThread().getName());
        super.onDestroy();
    }
    //Service暴露出去供client调用的公共方法
    public int getRestult() {
        return 10;
    }
}

client端要做的事情:
1.创建ServiceConnection类型实例,并重写onServiceConnected()方法和onServiceDisconnected()方法。
2.当执行到onServiceConnected回调时,可通过IBinder实例得到Service实例对象,这样可实现client与Service的连接。
3.onServiceDisconnected回调被执行时,表示client与Service断开连接,在此可以写一些断开连接后需要做的处理。

创建Activity1,代码如下:

public class Activity1 extends Activity implements View.OnClickListener {
    private static final String TAG = "Activity1";
    private SecondService service = null;
    private boolean isBind = false;
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            isBind = true;
            SecondService.MyBinder myBinder = (SecondService.MyBinder) binder;
            service = myBinder.getService();
            Log.e(TAG, "Activity1 - onServiceConnected");
            int num = service.getRestult();
            Log.e(TAG, "Activity1 - result = " + num);
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            isBind = false;
            Log.e(TAG, "Activity1 - onServiceDisconnected");
        }
    };
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_1);
        Log.e(TAG, "Activity1 - onCreate - Thread = " + Thread.currentThread().getName());
        findViewById(R.id.startService).setOnClickListener(this);
        findViewById(R.id.stopService).setOnClickListener(this);
        findViewById(R.id.bindService).setOnClickListener(this);
        findViewById(R.id.unBindService).setOnClickListener(this);
        findViewById(R.id.satart2Activity).setOnClickListener(this);
        findViewById(R.id.finish).setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.startService) {
            //单击了“bindService”按钮
            Intent intent = new Intent(this, SecondService.class);
            intent.putExtra("from", "Activity1");
            Log.e(TAG, "----------------------------------------------------------------------");
            Log.e(TAG, "Activity1 执行 startService");
          startService(intent);
        }  else if (v.getId() == R.id.stopService) {
            //单击了“bindService”按钮
            Intent intent = new Intent(this, SecondService.class);
            intent.putExtra("from", "Activity1");
            Log.e(TAG, "----------------------------------------------------------------------");
            Log.e(TAG, "Activity1 执行 stopService");
            stopService(intent);
        } else if (v.getId() == R.id.bindService) {
            //单击了“bindService”按钮
            Intent intent = new Intent(this, SecondService.class);
            intent.putExtra("from", "Activity1");
            Log.e(TAG, "----------------------------------------------------------------------");
            Log.e(TAG, "Activity1 执行 bindService");
            bindService(intent, conn, BIND_AUTO_CREATE);
        } else if (v.getId() == R.id.unBindService) {
            //单击了“unbindService”按钮
            if (isBind) {
                Log.e(TAG,
                        "----------------------------------------------------------------------");
                Log.e(TAG, "Activity1 执行 unbindService");
                unbindService(conn);
            }
        } else if (v.getId() == R.id.satart2Activity) {
            //单击了“start ActivityB”按钮
            Intent intent = new Intent(this, Activity2.class);
            Log.e(TAG,
                    "----------------------------------------------------------------------");
            Log.e(TAG, "Activity1 启动 Activity2");
            startActivity(intent);
        } else if (v.getId() == R.id.finish) {
            //单击了“Finish”按钮
            Log.e(TAG,
                    "----------------------------------------------------------------------");
            Log.e(TAG, "Activity1 执行 finish");
            this.finish();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (isBind) {
            unbindService(conn);
        }
        Log.e(TAG, "Activity1 - onDestroy");
    }
}

创建Activity2,代码如下:
public class Activity2 extends Activity implements View.OnClickListener {
    private static final String TAG = "Activity2";
    private SecondService service = null;
    private boolean isBind = false;
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            isBind = true;
            SecondService.MyBinder myBinder = (SecondService.MyBinder) binder;
            service = myBinder.getService();
            Log.i(TAG, "Activity2 - onServiceConnected");
            int num = service.getRestult();
            Log.i(TAG, "Activity2 - result = " + num);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            isBind = false;
            Log.i(TAG, "Activity2 - onServiceDisconnected");
        }
    };

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_2);
        Log.i(TAG, "Activity2 - onCreate - Thread = " + Thread.currentThread().getName());

        findViewById(R.id.bindService).setOnClickListener(this);
        findViewById(R.id.unBindService).setOnClickListener(this);
        findViewById(R.id.finish).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.bindService) {
            //单击了“bindService”按钮
            Intent intent = new Intent(this, SecondService.class);
            intent.putExtra("from", "Activity2");
            Log.i(TAG, "----------------------------------------------------------------------");
            Log.i(TAG, "Activity2 执行 bindService");
            bindService(intent, conn, BIND_AUTO_CREATE);
        } else if (v.getId() == R.id.unBindService) {
            //单击了“unbindService”按钮
            if (isBind) {
                Log.i(TAG,
                        "----------------------------------------------------------------------");
                Log.i(TAG, "Activity2 执行 unbindService");
                unbindService(conn);
            }
        } else if (v.getId() == R.id.finish) {
            //单击了“Finish”按钮
            Log.i(TAG,
                    "----------------------------------------------------------------------");
            Log.i(TAG, "Activity2 执行 finish");
            this.finish();
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "Activity2 - onDestroy");
    }
}

测试1,启动Activity1,点击bindService按钮,再点击unBindService,log输出如下:
04-27 16:55:06.260 21342-21342/com.jiusi.equiview E/Activity1: ----------------------------------------------------------------------
    Activity1 执行 bindService
04-27 16:55:06.270 21342-21342/com.jiusi.equiview E/SecondService: TestTwoService - onCreate - Thread = main
    TestTwoService - onBind - Thread = main
04-27 16:55:06.300 21342-21342/com.jiusi.equiview E/Activity1: Activity1 - onServiceConnected

04-27 16:57:24.380 21342-21342/com.jiusi.equiview E/Activity1: ----------------------------------------------------------------------
    Activity1 执行 unbindService
04-27 16:57:24.380 21342-21342/com.jiusi.equiview E/SecondService: TestTwoService - onUnbind - from = Activity1
    TestTwoService - onDestroy - Thread = main

调用bindService之后发生的事情:
1.client执行bindService()
2.如果Service不存在,则Service执行onCreate(),onBind()
3.client实例ServiceConnection执行onServiceConnected()方法

调用unbindService之后发生的事情:
1.client执行unbindService()
2.client与Service解除绑定连接状态
3.Service检测是否还有其他client与其连接,如果没有Service执行onUnbind()和onDestroy()

测试2 先点击Activity1的bindService按钮,再点击Activity1的Finish按钮,log输出:

04-27 17:08:34.400 25181-25181/com.jiusi.equiview E/Activity1: ----------------------------------------------------------------------

    Activity1 执行 bindService
04-27 17:08:34.410 25181-25181/com.jiusi.equiview E/SecondService: TestTwoService - onCreate - Thread = main
    TestTwoService - onBind - Thread = main
04-27 17:08:34.430 25181-25181/com.jiusi.equiview E/Activity1: Activity1 - onServiceConnected
    Activity1 - result = 10
04-27 17:09:10.080 25181-25181/com.jiusi.equiview E/Activity1: ----------------------------------------------------------------------
    Activity1 执行 finish
04-27 17:09:10.860 25181-25181/com.jiusi.equiview E/Activity1: Activity1 - onDestroy
04-27 17:09:10.860 25181-25181/com.jiusi.equiview E/SecondService: TestTwoService - onUnbind - from = Activity1
    TestTwoService - onDestroy - Thread = main
分析:如果client销毁,如果client没有与Service解除绑定,那么会报异常;client与Service先解除绑定就不会报异常。
测试3:step1: 点击Activity1的bindService按钮
step2: 点击Activity1的startActivity 1按钮,切换到Activity2
step3: 点击Activity2中的bindService按钮
step4: 点击Activity2中的unbindService按钮
step5: 点击Activity2中的Finish按钮
step6: 点击Activity1中的unbindService按钮
log输出:

04-27 17:32:08.210 29050-29050/com.jiusi.equiview E/Activity1: ----------------------------------------------------------------------
    Activity1 执行 bindService
04-27 17:32:08.210 29050-29050/com.jiusi.equiview E/SecondService: TestTwoService - onCreate - Thread = main
    TestTwoService - onBind - Thread = main
04-27 17:32:08.220 29050-29050/com.jiusi.equiview E/Activity1: Activity1 - onServiceConnected
    Activity1 - result = 10

04-27 17:33:45.080 29050-29050/com.jiusi.equiview E/Activity1: ----------------------------------------------------------------------
    Activity1 启动 Activity2
04-27 17:35:18.290 29050-29050/com.jiusi.equiview E/Activity2: ----------------------------------------------------------------------
    Activity2 执行 bindService
    Activity2 - onServiceConnected
    Activity2 - result = 10
04-27 17:38:27.750 30634-30634/com.jiusi.equiview E/Activity2: ----------------------------------------------------------------------
    Activity2 执行 finish
04-27 17:38:28.060 30634-30634/com.jiusi.equiview E/Activity2: Activity2 - onDestroy
04-27 17:39:07.470 30634-30634/com.jiusi.equiview E/Activity1: ----------------------------------------------------------------------
    Activity1 执行 unbindService
04-27 17:39:07.470 30634-30634/com.jiusi.equiview E/SecondService: TestTwoService - onUnbind - from = Activity1
    TestTwoService - onDestroy - Thread = main

总结bindService的生命周期:
1.点击ActivityA的bindService按钮
第一次调用bindService会实例化TestTwoService,然后执行其onBind()方法,得到IBinder类型的实例,将其作为参数传入ActivityA的ServiceConnection的onServiceConnected方法中,标志着Activity1与SecondService建立了绑定

2.点击Activity2中的bindService按钮
由于SecondService已处于运行状态,所以再次调用bindService不会重新创建它的实例,所以也不会执行SecondService的onCreate()方法和onBind()方法。Activity2与Activity1共享IBinder实例。此时有两个client与SecondService绑定

3.点击Activity2中的unbindService按钮
Activity2与SecondService解除了绑定,当没有任何client与Service绑定时,才会执行Service的onUnbind()方法。此时,Activity1还在绑定连接中,所以不会执行Service的解绑方法

4.点击Activity1中的unbindService按钮
Activity1执行unbindService之后,Activity1与SecondService就解除绑定了,这样就没有client与SecondService绑定,这时候Android会销毁SecondService,在销毁前会先执行SecondService的onUnbind()方法,然后才会执行其onDestroy()方法,这样SecondService就销毁了。

(三)通过startServie再bindService或者先bindService再startServie。

代码还是参考Activity1的代码,

1.先startServie,再bindService,log输出如下:

04-27 18:28:23.870 2479-2479/com.jiusi.equiview E/Activity1: ----------------------------------------------------------------------

    Activity1 执行 startService
04-27 18:28:23.880 2479-2479/com.jiusi.equiview E/SecondService: TestTwoService - onCreate - Thread = main

    TestTwoService - onStartCommand - startId = 1, Thread = main

04-27 18:29:29.050 2479-2479/com.jiusi.equiview E/Activity1: ----------------------------------------------------------------------
04-27 18:29:29.070 2479-2479/com.jiusi.equiview E/Activity1: Activity1 执行 bindService
04-27 18:29:29.070 2479-2479/com.jiusi.equiview E/SecondService: TestTwoService - onBind - Thread = main
04-27 18:29:29.100 2479-2479/com.jiusi.equiview E/Activity1: Activity1 - onServiceConnected

    Activity1 - result = 10

分析:onCreate方法只执行了一次,onStartCommand ->onBind ;

2.先bindService,再,log输出如下:startServie

04-27 18:37:25.910 4927-4927/com.jiusi.equiview E/Activity1: ----------------------------------------------------------------------
    Activity1 执行 bindService
04-27 18:37:25.920 4927-4927/com.jiusi.equiview E/SecondService: TestTwoService - onCreate - Thread = main
04-27 18:37:25.930 4927-4927/com.jiusi.equiview E/SecondService: TestTwoService - onBind - Thread = main
04-27 18:37:25.930 4927-4927/com.jiusi.equiview E/Activity1: Activity1 - onServiceConnected

    Activity1 - result = 10

04-27 18:38:06.320 4927-4927/com.jiusi.equiview E/Activity1: ----------------------------------------------------------------------
    Activity1 执行 startService

04-27 18:38:06.320 4927-4927/com.jiusi.equiview E/SecondService: TestTwoService - onStartCommand - startId = 1, Thread = main

分析:onCreate方法只执行了一次,onBind ->onStartCommand;

3.当startService和bindService后,再多次执行startService,log输出:

04-27 18:44:57.120 5851-5851/com.jiusi.equiview E/Activity1: ----------------------------------------------------------------------
    Activity1 执行 startService

04-27 18:44:57.130 5851-5851/com.jiusi.equiview E/SecondService: TestTwoService - onStartCommand - startId = 2, Thread = main

分析:和startService多次启动结果一样,onStartCommand执行了多次;

4.当startService和bindService后,再多次执行bindService,已经绑定的service不会再执行service的方法。

5.当startService和bindService后,执行stopService,log输出如下:

04-27 18:48:26.750 5851-5851/com.jiusi.equiview E/Activity1: ----------------------------------------------------------------------

    Activity1 执行 stopService

分析,并没有执行service的onDestroy方法,可见service并没有停止。

6.当startService和bindService后,执行unBindService,log输出如下:

04-27 18:50:12.410 7171-7171/com.jiusi.equiview E/Activity1: ----------------------------------------------------------------------
    Activity1 执行 unbindService
04-27 18:50:12.410 7171-7171/com.jiusi.equiview E/SecondService: TestTwoService - onUnbind - from = Activity1

分析,并没有执行service的onDestroy方法,只是执行了SecondService的onUnbind ,可见Service并没有停止。

7.当startService和bindService后,执行unBindService,再执行stopService; log输出如下:

04-27 19:02:45.320 8952-8952/com.jiusi.equiview E/SecondService: TestTwoService - onDestroy - Thread = main

分析,这个时候Service销毁了。

8.当startService和bindService后,执行stopService,再执行unBindService; log输出如下:

04-27 19:03:59.210 8952-8952/com.jiusi.equiview E/SecondService: TestTwoService - onUnbind - from = Activity1
    TestTwoService - onDestroy - Thread = main

分析,这个时候Service也被销毁了。

总结:如果即startService又bindService,必须要执行stopService和unBindService Service才会被销毁。

Service相关的知识基本就先总结到这里,在下一篇博客里会讲述Sevice其它方面的一些知识,如有不合理之处欢迎拍砖。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值