android里面的Service是四大组件之一,也是项目中必然需要使用的内容。Service分为绑定服务和非绑定服务,绑定服务是与Activity进行绑定,如果Activity结束绑定的Service也结束,非绑定服务理论上除非调用stopService停止服务则服务不会停止。
使用服务时必须在AndroidManifest先进行配置
<service android:name=".BackGroupService"> </service> <service android:name=".LocalService"> </service> <service android:name=".ForegroundService"> </service> <service android:name=".MyIntentService"> </service>
然后再打开服务
Intent intent = new Intent(context,BackGroupService.class); startService(intent)
首先是非绑定的服务
package com.kkrs.serivce; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.support.annotation.Nullable; import android.util.Log; /** * Created by zd on 2018/12/17. */ // 非绑定的service public class BackGroupService extends Service { private boolean flag = true; @Override public void onCreate() { super.onCreate(); Log.e("Service","onCreate"); flag = true; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e("Service","onStartCommand"); //在这里开线程来使用耗时操作 new Thread(){ @Override public void run() { super.run(); while (flag) { try { sleep(2000); Log.e("Service", "doSomeThing"); } catch (Exception e) { e.printStackTrace(); } } } }.start(); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); flag = false; Log.e("Service","onDestroy"); } @Nullable @Override public IBinder onBind(Intent intent) { Log.e("Service","onBind"); return null; } }
打开服务生命周期为 onCreate -> onStartCommand
如果服务本身是打开的则直接进入 onStartCommand
关闭服务的生命周期则是进入 onDestory
然后是绑定的服务
绑定服务需要使用ServiceConnection对服务进行连接,在activity中绑定的部分代码:
/** * ServiceConnection代表与服务的连接,它只有两个方法, * onServiceConnected和onServiceDisconnected, * 前者是在操作者在连接一个服务成功时被调用,而后者是在服务崩溃或被杀死导致的连接中断时被调用 */ private ServiceConnection conn; private LocalService mService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); context = this; setContentView(R.layout.activity_main); btnBind = (Button)findViewById(R.id.btnBind); btnUnBind = (Button)findViewById(R.id.btnUnBind); btnGetDatas = (Button)findViewById(R.id.btnGetDatas); conn = new ServiceConnection() { /** * 与服务器端交互的接口方法 绑定服务的时候被回调,在这个方法获取绑定Service传递过来的IBinder对象, * 通过这个IBinder对象,实现宿主和Service的交互。 */ @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.e("MainActivity", "绑定成功调用:onServiceConnected"); // 获取Binder LocalService.LocalBinder binder = (LocalService.LocalBinder) service; mService = binder.getService(); } /** * 当取消绑定的时候被回调。但正常情况下是不被调用的,它的调用时机是当Service服务被意外销毁时, * 例如内存的资源不足时这个方法才被自动调用。 */ @Override public void onServiceDisconnected(ComponentName name) { mService=null; } }; final Intent intent = new Intent(this, LocalService.class); btnBind.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Log.e("MainActivity", "绑定调用:bindService"); bindService(intent, conn, Service.BIND_AUTO_CREATE); } }); btnUnBind.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 解除绑定 Log.e("MainActivity", "解除绑定:bindService"); if(mService!=null) { Log.e("MainActivity", "mService!=null"); mService = null; unbindService(conn); } } }); btnGetDatas.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mService != null) { // 通过绑定服务传递的Binder对象,获取Service暴露出来的数据 Log.e("MainActivity", "从服务端获取数据:" + mService.getCount()); } else { Log.e("MainActivity", "还没绑定呢,先绑定,无法从服务端获取数据"); } } }); }
对于绑定服务的代码
//绑定的service public class LocalService extends Service { private final static String TAG = "LocalService"; private int count; private boolean quit; private Thread thread; private LocalBinder binder = new LocalBinder(); @Override public void onCreate() { super.onCreate(); Log.e(TAG, "Service is invoke Created"); thread = new Thread(new Runnable() { @Override public void run() { // 每间隔一秒count加1 ,直到quit为true。 while (!quit) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } count++; } } }); thread.start(); } public class LocalBinder extends Binder { // 声明一个方法,getService。(提供给客户端调用) LocalService getService() { // 返回当前对象LocalService,这样我们就可在客户端端调用Service的公共方法了 return LocalService.this; } } /** * 公共方法 * @return */ public int getCount(){ return count; } @Override public void onDestroy() { Log.e(TAG, "Service is onDestroy"); this.quit = true; super.onDestroy(); } @Override public boolean onUnbind(Intent intent) { Log.e(TAG, "Service is onUnbind"); return super.onUnbind(intent); } @Nullable @Override public IBinder onBind(Intent intent) { Log.e(TAG, "Service is onBind"); return binder; } }
绑定 Created->onBind
绑定时获得数据 onServiceConnected
解除绑定 onUnbind -> onDestroy
一般来讲在服务中使用耗时操作都会新创建一个线程,在线程中来处理,但是在线程的创建和判断则需要一些逻辑来判断。但是Android提供了一个专门用了执行耗时操作的Service,IntentService,使用这个就不需要在对你创建的线程进行处理,在这里将服务里面创建一个通知来显示服务的运行情况。
//耗时服务 public class MyIntentService extends IntentService { private boolean flag = true; private int num = 0; //需要一个空构造函数 public MyIntentService() { super("MyIntentService"); // 调用父类的有参构造函数 } public MyIntentService(String name) { super(name); Log.e("MyIntentService","MyIntentService"); } @Override public void onCreate() { super.onCreate(); Log.e("MyIntentService","onCreate"); } @Override public void onStart(@Nullable Intent intent, int startId) { super.onStart(intent, startId); flag = true; Log.e("MyIntentService","onStart"); } @Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) { Log.e("MyIntentService","onStartCommand"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { Log.e("MyIntentService","onDestroy"); super.onDestroy(); flag = false; } //这里进行耗时操作 @Override protected void onHandleIntent(@Nullable Intent intent) { Log.e("MyIntentService","onHandleIntent"); final Context context = this.getApplicationContext(); while (flag){ try { sleep(2000); Log.e("MyIntentService","start Intent"); if (num > 100){ num = 0; } Notification notification = new Notification.Builder(context) .setContentTitle("前台服务的标题") .setContentText("这是一个前台服务 "+num) .setSmallIcon(R.mipmap.ic_launcher) .setWhen(System.currentTimeMillis()) .build(); startForeground(110, notification);// 开始前台服务 num = num + 1; }catch (Exception e){ } } } }
打开服务生命周期为 onCreate -> onStartCommand->onStart->onHandleIntent
如果服务本身是打开的则直接进入 onStartCommand->onStart
关闭服务的生命周期则是进入 onDestory