Service 简介
Service 是Android四大组件之一,在我们日常的开发中会经常用到,主要用于做一些耗时的后台工作,或者用于运行一些需要长期运行的任务 有的时候需要在程序退出的时候,需要service在后台运行,并在合适的场景中作出完成一些任务,如推送后台播放音乐等。
Service 的生命周期
Service 作为Android 的四大组件同样也有生命周期,你可以在Service生命周期的不同阶段做一些相应的操作。
Service 的生命周期不同于Activity的生命周期。通过StartServce()启动的服务的生命周期如左图所示,通过BindService()启动的服务的生命周期如右图所示,无论通过何种方式启动的服务都会执行OnCreate()和onDestroy(),我们可以在Oncreate() 中做一些初始化操作,在OnDestroy()中将一些资源释放掉。如我们通过服务在后台播放音乐的时候,可以在OnCreate()方法中开启一个任务线程,来执行播放音乐的操作,在OnDestroy()中将线程资源释放掉。
启动方式的区别:
1.通过startService()方式启动的服务,服务与启动者之间就没有关联了,通过StopService()来结束服务。服务能够被多次启动,但是一个服务的生命周期总onCreate()方法只会被执行一次,onStartCommand()会被执行多次。
2.通过BindService()启动的服务,大多数都是为了Activity和Service之间进行通信,因此当Activity销毁的时候,Service也会被销毁掉。
一个Service可以被多个客户端绑定,
在Service中定义一个Bind的子类,并定义一些接口,Activity通过BindService()获取这个子类,并调用相应的接口,实现内部通信。
注意:Android5.0及以上不能通过直接通过隐式的方式启动服务,否则会报错: Service Intent must be explicit: Intent解决方案有两种:1.google推荐使用的:Intent intent = new Intent(Action);intent.setPackage(packageName)2.直接通过显示的方式启动服务:Intent intent = new Intent(context, XXXX.class);
Service 的基本使用
首先创建一个Service的子类。package com.example.servicetest.service; import android.app.Service; import android.content.Intent; import android.content.ServiceConnection; import android.content.res.Configuration; import android.os.Binder; import android.os.IBinder; import android.util.Log; public class MyService extends Service { private String TAG = MyService.class.getSimpleName(); private Binder mBinder = new MyBinder(); @Override public IBinder onBind(Intent intent) { return mBinder; } @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand"); return super.onStartCommand(intent, flags, startId); } @Override public boolean bindService(Intent service, ServiceConnection conn, int flags) { Log.d(TAG, "bindService"); return super.bindService(service, conn, flags); } @Override public boolean onUnbind(Intent intent) { Log.d(TAG, "onUnbind"); return super.onUnbind(intent); } @Override public void onDestroy() { Log.d(TAG, "onDestroy"); super.onDestroy(); } public class MyBinder extends Binder{ public void downLoad(){ Log.d(TAG, "下载"); }; } }
由于Service是Android的四大组件之一,因此要在Android.maininfast.xml文件中声明最后在Activity中执行相应的Service操作,来观察Service的生命周期。<service android:name="com.example.servicetest.service.MyService"/>
package com.example.servicetest; import com.example.servicetest.service.MyService; import com.example.servicetest.service.MyService.MyBinder; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity implements OnClickListener { private Button mBtnStartService = null; private Button mBtnStopService = null; private Button mBtnBindService = null; private Button mBtnUnBindService = null; private Button mBtnDownload = null; private MyBinder mBinder = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBtnStartService = (Button) findViewById(R.id.button1); mBtnStopService = (Button) findViewById(R.id.button2); mBtnBindService = (Button) findViewById(R.id.button3); mBtnUnBindService = (Button) findViewById(R.id.button4); mBtnDownload = (Button) findViewById(R.id.button5); mBtnStartService.setOnClickListener(this); mBtnStopService.setOnClickListener(this); mBtnBindService.setOnClickListener(this); mBtnUnBindService.setOnClickListener(this); mBtnDownload.setOnClickListener(this); } @Override public void onClick(View v) { Intent intent = new Intent(this, MyService.class); switch (v.getId()) { case R.id.button1: startService(intent); break; case R.id.button2: stopService(intent); break; case R.id.button3: bindService(intent, con, Context.BIND_AUTO_CREATE); break; case R.id.button4: unbindService(con); break; case R.id.button5: mBinder.downLoad(); break; default: break; } } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Intent intent = new Intent(this, MyService.class); stopService(intent); unbindService(con); } private ServiceConnection con = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mBinder = (MyBinder) service; Log.d("MyService", "onServiceConnected"); } @Override public void onServiceDisconnected(ComponentName name) { mBinder = null; } }; }
这个界面如下1.通过StartService()的方式启动服务,输出的log如下:
当我们再次执行StartService的时候
只会调用onStartCommand(Intent intent, int flags, int startId)放法,所以我们知道通过startService的方式启动服务,onCreate之被执行一次, onStartCommand被执行多次,服务可被多次启动。2.通过BindService启动服务,输出的log如下:
多个客户端可以绑定一个服务,但是Oncreate只会被调用一次。我们在绑定服务后将服务中自己定义的Bind类传到客户端,然后在客户端调用,完成客户端与服务的通信。public class MyBinder extends Binder{ public void downLoad(){ Log.d(TAG, "下载"); }; }
private Binder mBinder = new MyBinder(); @Override public IBinder onBind(Intent intent) { return mBinder; }
Service中的注意事项我们知道Service主要用于在后台做一些耗时的操作,但是有一点要注意的是Service其实是运行在主线程中,如果在Service中的操作耗时超过5秒就会发生ANR错误。
所以一般,我们在Service的onCreate方法中做一些初始化操作,耗时的操作要在线程中执行。