Service与Thread线程的区别
其实他们两者并没有太大的关系,不过有很多朋友经常把这两个混淆了!Thread是线程,程序执行的最小单元,分配CPU的基本单位!而Service则是Android提供一个允许长时间留驻后台的一个组件,最常见的用法就是做轮询操作!或者想在后台做一些事情,比如后台下载更新!记得别把这两个概念混淆!
Service的生命周期图
(下图借于code_pig大神,总结的很好,大家一块学习!)
Service服务的相关方法介绍:
1、onCreate():当Service第一次被创建后立即调用该方法,该方法在Service的生命周期里只被调用一次!
2、onDestory():当Service被关闭时调用该方法,该方法只被调用一次!
3、onStartCommand():当Service被调用时,调用该方法。该方法可被重复调用,并且不会创建新的Service对象,而是复用前面产生的Service对象。
4、onBind():这是Service必须实现的方法,该方法会返回一个IBinder对象,APP通过该对象与Service组件进行通信。
5、onUnBind():当该Service绑定的所有客户端都断开时调用该方法。
Android中使用Service的方式有两种:1)StartService()启动Service
2)BindService()启动ServicePS:还有一种,就是启动Service后,绑定Service!
效果图如下:
第一种:主要代码如下:
TestServiceOne.java
package com.deepreality.servicedemo; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.support.annotation.Nullable; import android.util.Log; //Android的四大组件,只有定义了,就必须去AndroidManifest.xml中注册一下!!! public class TestServiceOne extends Service { private final String TAG = "TestServiceOne"; //必须实现的方法 @Nullable @Override public IBinder onBind(Intent intent) { Log.e(TAG, "onBind方法被调用"); return null; } //Service被创建时调用 @Override public void onCreate() { Log.e(TAG, "onCreate方法被调用"); super.onCreate(); } //Service被启动时调用 @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e(TAG, "onStartCommand方法被调用"); return super.onStartCommand(intent, flags, startId); } //Service被销毁时调用 @Override public void onDestroy() { Log.e(TAG, "onDestroy方法被调用"); super.onDestroy(); } }
MainActivity.java的代码如下:
package com.deepreality.servicedemo; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; //验证StartService启动Service的调用顺序 public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button btnServiceStart, btnServiceStop; private Intent intent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnServiceStart = findViewById(R.id.main_btnServiceStart); btnServiceStop = findViewById(R.id.main_btnServiceStop); btnServiceStart.setOnClickListener(this); btnServiceStop.setOnClickListener(this); intent = new Intent(); intent.setAction("com.deepreality.servicedemo.service.TEST_SERVICE_ONE"); //Android 5.0之后,隐式调用是除了设置setAction()外,还需要设置setPackage(); intent.setPackage("com.deepreality.servicedemo"); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.main_btnServiceStart:{ startService(intent); break; } case R.id.main_btnServiceStop:{ stopService(intent); break; } default:break; } } }
第二种:
TestServiceTwo.java的主要代码如下:
package com.deepreality.servicedemo; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.support.annotation.Nullable; import android.util.Log; public class TestServiceTwo extends Service { private final String TAG = "TestServiceTwo"; private int count = 0; private boolean quit = false; private MyBinder myBinder = new MyBinder(); //定义onBinder方法所返回的对象 public class MyBinder extends Binder { public int getCount() { return count; } } //必须实现的方法 @Nullable @Override public IBinder onBind(Intent intent) { Log.e(TAG, "onBind方法被调用"); return myBinder; } //Service被创建时调用 @Override public void onCreate() { Log.e(TAG, "onCreate方法被调用"); super.onCreate(); new Thread(new Runnable() { @Override public void run() { while (!quit) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } count ++; } } }).start(); } //Service断开连接时回调 @Override public boolean onUnbind(Intent intent) { Log.e(TAG, "onUnbind方法被调用!"); return true; } //Service被销毁时调用 @Override public void onDestroy() { super.onDestroy(); Log.e(TAG, "onDestroy方法被调用"); this.quit = true; } @Override public void onRebind(Intent intent) { super.onRebind(intent); Log.e(TAG, "onRebind方法被调用!"); } }
MainActivityTwo.java的代码如下:
package com.deepreality.servicedemo; import android.app.Service; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.Toast; //验证BindService启动Service的顺序 public class MainActivityTwo extends AppCompatActivity implements View.OnClickListener { private Button btnServiceStart, btnServiceStop, btnServiceStatus; private Intent intent; //保持所启动的Service的IBinder对象,同时定义一个ServiceConnection对象 TestServiceTwo.MyBinder myBinder; private ServiceConnection serviceConnection = new ServiceConnection() { //Activity与Service连接成功时回调该方法 @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.e("Service Connected", "success!"); myBinder = (TestServiceTwo.MyBinder) service; } //Activity与Service断开连接时回调该方法 @Override public void onServiceDisconnected(ComponentName name) { Log.e("Service Disconnected", "error!"); } }; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnServiceStart = findViewById(R.id.main_btnServiceStart); btnServiceStop = findViewById(R.id.main_btnServiceStop); btnServiceStatus = findViewById(R.id.main_btnServiceStatus); btnServiceStart.setOnClickListener(this); btnServiceStop.setOnClickListener(this); btnServiceStatus.setOnClickListener(this); intent = new Intent(); intent.setAction("com.deepreality.servicedemo.service.TEST_SERVICE_TWO"); //Android 5.0之后,隐式调用是除了设置setAction()外,还需要设置setPackage(); intent.setPackage("com.deepreality.servicedemo"); } @Override protected void onDestroy() { super.onDestroy(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.main_btnServiceStart:{ //绑定service bindService(intent, serviceConnection, Service.BIND_AUTO_CREATE); break; } case R.id.main_btnServiceStop:{ //解除绑定 unbindService(serviceConnection); break; } case R.id.main_btnServiceStatus:{ int count = myBinder.getCount(); Toast.makeText(MainActivityTwo.this, "Service的count值:" + count, Toast.LENGTH_SHORT).show(); break; } default:break; } } }
注意事项:在OnBind()方法中需返回一个IBinder实例,不然onServiceConnected方法不会调用!!!
AndroidManifest.xml的代码如下:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.deepreality.servicedemo"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> </activity> <activity android:name=".MainActivityTwo"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- 配置Service组件,同时配置一个action --> <service android:name=".TestServiceOne"> <intent-filter> <action android:name="com.deepreality.servicedemo.service.TEST_SERVICE_ONE"/> </intent-filter> </service> <!-- 配置Service组件,同时配置一个action --> <service android:name=".TestServiceTwo" android:exported="false"> <intent-filter> <action android:name="com.deepreality.servicedemo.service.TEST_SERVICE_TWO"/> </intent-filter> </service> </application> </manifest>