服务(Service)是Android中实现程序后台运行的解决方案,它非常适合用于去执行那些不需要和用户交互而且还要求长期运行的任务。服务的运行不依赖于任何用户界面,即使当程序被切换到后台,或者用户打开了另外一个应用程序,服务仍然能够保持正常运行。
不过需要注意的是,服务并不是运行在一个独立的进程当中的,而是依赖于创建服务时所在的应用程序进程。当某个应用程序进程被杀掉时,所有依赖于该进程的服务也会停止运行。
另外,也不要被服务的后台概念所迷惑,实际上服务并不会自动开启线程,所有的代码都是默认运行在主线程当中的。也就是说,我们需要在服务的内部手动创建子线程,并在这里执行具体的任务,否则就有可能出现主线程被阻塞住的情况。
一个简单的演示
创建服务类:
public class MyService extends Service { @Nullable //onBind是Service中的唯一抽象方法 @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); Log.d("serviceTest","service onCreate"); } @Override public void onDestroy() { super.onDestroy(); Log.d("serviceTest", "Service onDestroy"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("serviceTest","Service onStartCommand"); return super.onStartCommand(intent, flags, startId); } }
主活动
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Button startService; private Button stopService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startService = (Button) findViewById(R.id.start_service); stopService = (Button) findViewById(R.id.stop_service); startService.setOnClickListener(this); stopService.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.start_service: Intent startIntent = new Intent(this, MyService.class); startService(startIntent); // 启动服务 break; case R.id.stop_service: Intent stopIntent = new Intent(this, MyService.class); stopService(stopIntent); // 停止服务 break; default: break; } } }以上代码可以看出布局为两个button,用以控制服务的启动与停止
Android惯例(不解释):
onCreate()方法是在服务第一次创建的时候调用的,而onStartCommand()方法则在每次启动服务的时候都会调用。
活动与服务的联动(onBind)
public class MyService extends Service { //活动与服务的联动 private DownloadBinder mBinder = new DownloadBinder(); //内部类为活动提供控制服务中下载功能的接口 class DownloadBinder extends Binder { public void startDownload() { Log.d("serviceTest", "startDownload executed"); } public int getProgress() { Log.d("serviceTest", "getProgress executed"); return 0; } } @Nullable //onBind是Service中的唯一抽象方法,bindService方法会回调该方法以获取IBbinder实例 @Override public IBinder onBind(Intent intent) { //返回内部类对象 return mBinder; } @Override public void onCreate() { super.onCreate(); Log.d("serviceTest", "service onCreate"); } @Override public void onDestroy() { super.onDestroy(); Log.d("serviceTest", "Service onDestroy"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("serviceTest","Service onStartCommand"); return super.onStartCommand(intent, flags, startId); } }在活动中添加内部类的实例(serviceConnection)作为bindService的参数
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Button startService; private Button stopService; private Button bindService; private Button unbindService; private MyService.DownloadBinder downloadBinder; private ServiceConnection serviceConnection = new ServiceConnection() { //成功绑定 @Override public void onServiceConnected(ComponentName name, IBinder service) { //Bindler是Android中的一种跨进程通信方式,它实现了IBinder接口 downloadBinder = (MyService.DownloadBinder) service;//向下转型 downloadBinder.getProgress(); downloadBinder.startDownload(); } //解除绑定 @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startService = (Button) findViewById(R.id.start_service); stopService = (Button) findViewById(R.id.stop_service); startService.setOnClickListener(this); stopService.setOnClickListener(this); bindService = (Button) findViewById(R.id.bind_service); unbindService = (Button) findViewById(R.id.unbind_service); bindService.setOnClickListener(this); unbindService.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.start_service: Intent startIntent = new Intent(this, MyService.class); startService(startIntent); // 启动服务 break; case R.id.stop_service: Intent stopIntent = new Intent(this, MyService.class); stopService(stopIntent); // 停止服务 break; //BIND_AUTO_CREATE 表示在活动和服务进行绑定后自动创建服务 case R.id.bind_service: Intent bindIntent = new Intent(this, MyService.class); bindService(bindIntent, serviceConnection, BIND_AUTO_CREATE); // 绑定服务 break; case R.id.unbind_service: unbindService(serviceConnection); // 解绑服务 break; default: break; } } }布局如下:
结果演示:
服务的生命周期
一旦在项目的任何位置调用了 Context的 startService()方法,相应的服务就会启动,并回调onStartCommand()方法。如果这个服务之前还没有创建过,onCreate()方法会先于onStartCommand()方法执行。服务启动了之后会一直保持运行状态,直到stopService()或stopSelf()方法被调用。注意虽然每调用一次startService()方法,onStartCommand()就会执行一次,但实际上每个服务都只会存在一个实例。所以不管你调用了多少次startService()方法,只需调用一次stopService()或stopSelf()方法,服务就会停止下来了。
若对一个服务既调用了startService()方法,又调用了bindService()方法,如何才能让服务销毁掉呢?
根据Android 系统的机制,一个服务只要被启动或者被绑定了之后,就会一直处于运行状态,必须要让以上两种条件同时不满足,服务才能被销毁。所以,这种情况下要同时调用 stopService()和 unbindService()方法,onDestroy()方法才会执行。
最简单的使用了,以后水平够了补上源码角度的解析,,,额,还有个IntentService呢,回头和多线程编程一起补上。