Android Serivce
Serivce是Android四大组件之一,主要用于后台操作。
一、Service的启动和停止(startService、stopService):
-
1.1 先新建Serivce操作类继承自系统的Serivce类,并重写onBind()、onCreate()、onDestroy()方法,如下所示:
public class EchoService extends Service { @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return null; } @Override public void onCreate() { Log.i("EchoSerivce", "onCreate"); } @Override public void onDestroy() { Log.i("EchoSerivce", "onDestroy"); } }
- 1.2 在AndroidManifest.xml中注册Serivce,如下所示:
<service android:name="EchoService"></service>
- 1.3 在相应的Activity操作类中通过Intent控制Serivce操作类,如下所示:
Intent intent = new Intent(MainActivity.this, EchoService.class); startService(intent); stopService(intent);
二、Service的绑定和解绑(bindService、 unbindService):
- 2.1 在一的基础上,EchoSerivce类中添加Binder的子类,如下所示:
private EchoServiceBinder echoServiceBinder = new EchoServiceBinder(); private final class EchoServiceBinder extends Binder { }
- 2.2 在EchoSerivce类中onBind()方法中添加返回内容,如下所示:
@Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub Log.i("EchoService", "onBind"); return echoServiceBinder; }
-
2.3 在相应的Activity操作类中添加实现ServiceConnection接口的类,并进行Service的绑定与解绑操作,如下所示:
EchoServiceConnection echoServiceConnection = new EchoServiceConnection(); private final class EchoServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName arg0, IBinder arg1) { // TODO Auto-generated method stub Log.i("EchoService", "onServiceConnected"); } @Override public void onServiceDisconnected(ComponentName arg0) { // TODO Auto-generated method stub Log.i("EchoService", "onServiceDisonnected"); } } bindService(intent, echoServiceConnection, Context.BIND_AUTO_CREATE); unbindService(echoServiceConnection);
如果同时进行了startService()和bindService()操作,则要停止相应的Service就要执行stopService()和unbindService()两个方法。
通过startService()方法启动的服务是不随Activity的死亡而停止,必须要有相应的方法去停止该服务。而通过bindService()方法启动的服务会随着Activity的死亡而停止,这种方式启动的服务如同该方法的名字一般是和Activity绑定在一起的。
三、与Service进行通信
如果Activity要和Service进行通信,就必须要用到bindService()这个方法,而不能简单使用startService()方法,而且通信要用到的媒介就是binder类。
首先在Service类中实现Binder的子类并在其中添加返回当前Service类实例对象的方法,然后在Service类中的onBind()方法中返回该Binder子类的实例对象,则可以在Activity中通过ServiceConnection接口中的onServiceConnected()方法取得该Binder子类的实例对象取得Service实例并与其进行通信。
具体操作看完整Demo。
完整Demo如下:
activity_main.xml
<LinearLayout 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:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
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/btn_startservice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="startservice" />
<Button
android:id="@+id/btn_stopservice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="stopservice" />
<Button
android:id="@+id/btn_bindservice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="bindservice" />
<Button
android:id="@+id/btn_unbindservice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="unbindservice" />
<Button
android:id="@+id/btn_getcurrentnum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="get current number" />
</LinearLayout>
MainActivity.java
public class MainActivity extends Activity {
private Button btn_startservice;
private Button btn_stopservice;
private Button btn_bindservice;
private Button btn_unbindservice;
private Button btn_getcurrentnum;
private Intent serviceIntent;
private BtnServiceListener btnServiceListener;
private EchoServiceConnection echoServiceConnection;
private EchoService echoService = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_startservice = (Button) findViewById(R.id.btn_startservice);
btn_stopservice = (Button) findViewById(R.id.btn_stopservice);
btn_bindservice = (Button) findViewById(R.id.btn_bindservice);
btn_unbindservice = (Button) findViewById(R.id.btn_unbindservice);
btn_getcurrentnum = (Button) findViewById(R.id.btn_getcurrentnum);
btnServiceListener = new BtnServiceListener();
echoServiceConnection = new EchoServiceConnection();
serviceIntent = new Intent(MainActivity.this, EchoService.class);
btn_startservice.setOnClickListener(btnServiceListener);
btn_stopservice.setOnClickListener(btnServiceListener);
btn_bindservice.setOnClickListener(btnServiceListener);
btn_unbindservice.setOnClickListener(btnServiceListener);
btn_getcurrentnum.setOnClickListener(btnServiceListener);
}
//按钮绑定事件
private final class BtnServiceListener implements OnClickListener {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_startservice:
startService(serviceIntent);
break;
case R.id.btn_stopservice:
stopService(serviceIntent);
break;
case R.id.btn_bindservice:
bindService(serviceIntent, echoServiceConnection,
Context.BIND_AUTO_CREATE);
break;
case R.id.btn_unbindservice:
unbindService(echoServiceConnection);
echoService = null;
break;
case R.id.btn_getcurrentnum:
if(echoService != null) {
Log.i("MainActivity",
"当前服务的数字:" + echoService.getCurrentNum());
}
break;
default:
break;
}
}
}
//ServiceConnection
private final class EchoServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
// TODO Auto-generated method stub
Log.i("EchoService", "onServiceConnected");
echoService = ((EchoService.EchoServiceBinder)binder).getSerivce();
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub
Log.i("EchoService", "onServiceDisonnected");
}
}
}
EchoService.java
public class EchoService extends Service {
private Timer timer = null;
private TimerTask timerTask = null;
private int i = 0;
public void startTimer() {
if(timer == null) {
timer = new Timer();
timerTask = new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
i++;
Log.i("EchoService", i + "");
}
};
timer.schedule(timerTask, 1000, 1000);
}
}
public void stopTimer() {
if(timer != null) {
timerTask.cancel();
timer.cancel();
timerTask = null;
timer = null;
}
}
public EchoServiceBinder echoServiceBinder = new EchoServiceBinder();
public final class EchoServiceBinder extends Binder {
public EchoService getSerivce() {
return EchoService.this;
}
}
public int getCurrentNum() {
return i;
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
Log.i("EchoService", "onBind");
return echoServiceBinder;
}
@Override
public void onCreate() {
Log.i("EchoSerivce", "onCreate");
startTimer();
}
@Override
public void onDestroy() {
Log.i("EchoSerivce", "onDestroy");
stopTimer();
}
}