一个Service 是一段长生命周期的,没有用户界面的程序,可以用来开发如监控类程序。
一个比较好的例子就是一个正在从播放列表中播放歌曲的媒体播放器。
在一个媒体播放器的应用中,应该会有多个activity,让使用者可以选择歌曲并播放歌曲。然而,音乐播放这个功能并没有对应的activity,因为使用者当然会认为在导航到其它屏幕时音乐应该还在播放的。在这个例子中,媒体播放器这个activity 会使用Context.startService()来启动一个service,从而可以在后台保持音乐的播放。同时,系统也将保持这个service 一直执行,直到这个service 运行结束。另外,我们还可以通过使用Context.bindService()方法,连接到一个service 上(如果这个service 还没有运行将启动它)。当连接到一个service 之后,可以通过service 提供的接口与它进行通讯。拿媒体播放器这个例子来说,就是我们可以进行暂停、重播等操作。
1)继承service类
2)AndroidManifast.xml配置清单文件中<application>节点里对服务进行配置
<service name=".SMSService"/>3)通过Contex.startService()或Contex.bindService()启动服务。
通过startService()方法启动的服务于调用者没有关系,即使调用者关闭了,服务仍然运行,想停止服务要调用Context.stopService(),此时系统会调用onDestory(),使用此方法启动时,服务首次启动系统先调用服务的onCreate()-->onStart(),如果服务已经启动再次调用只会触发onStart()方法。
上面的例子中,Activity发出一个信号,Service就启动了,但是Service具体做什么事情Activity是不知道的。下面举个栗子,演示一下如何让Activity与Service之间进行通信。
MyService
import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; import android.widget.Toast; public class MyService extends Service { public MyService() { } @Override public void onCreate() { super.onCreate(); } @Override public void onDestroy() { super.onDestroy(); Log.d("Debug", "onDestroy() invoked!"); } @Override public IBinder onBind(Intent intent) { return new MyBinder(); } public class MyBinder extends Binder { public void startDownload() { Log.d("Debug", "startDownload() invoked!"); Toast.makeText(getApplicationContext(),"startDownload()",Toast.LENGTH_LONG).show(); } } }
import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Button; import com.example.daniel.serviceactivitycommunication.service.MyService; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private MyService.MyBinder myBinder; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.d("Debug", "onServiceConnected!"); myBinder = (MyService.MyBinder) service; myBinder.startDownload(); } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button bindServiceBtn = (Button) findViewById(R.id.bind_service_btn); Button unbindServiceBtn = (Button) findViewById(R.id.unbind_service_btn); bindServiceBtn.setOnClickListener(this); unbindServiceBtn.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.bind_service_btn: Intent intent = new Intent(this, MyService.class); bindService(intent, connection, BIND_AUTO_CREATE); break; case R.id.unbind_service_btn: unbindService(connection); break; default: break; } } }
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <Button android:id="@+id/bind_service_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Bind Service" /> <Button android:id="@+id/unbind_service_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/bind_service_btn" android:text="Unbind Service" /> </RelativeLayout>
流程如下:
(1) 新建MyService,重写onBind方法,新建内部类MyBinder
(2)在Activity中新建ServiceConnection匿名类,重写类中的两个方法
(3)在Activity中BindServic这个Button的onClick方法中调用了bindService这个方法,使得Activity和Service进行绑定。
(1)为了使Activity能控制Service,Activity中必须有Service的实例。
当Activity与Service进行绑定的时候会调用ServiceConnection.onServiceConnected()方法,在这个方法中会回调Service的onBind()方法,进而在Activity中得到MyService中的Binder,这样就能在Activity中获得了Service的实例。
(2)ServiceConnection.onServiceDisconnected()
当Service崩溃或者被kill的时候调用,当客户端解除绑定的时候,不调用。
(3)使用bindService()启动的服务与调用者绑定,只要调用者关闭服务就终止。
使用此方法启动时,服务首次启动系统先调用服务的onCreate()-->onBind(),如果服务已经启动再次调用不会再触发这2个方法,调用者退出时系统会调用服务的onUnbind()-->onDestory(),想主动解除绑定可使用Contex.unbindService(),系统依次调用onUnbind()-->onDestory()。在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。
源码下载