概述
远程Service和本地Service不同之处在于,前者使用binderService()和unbinderServicec()方式启动和关闭服务,后者是使用startService()和stopService()方法启动或关闭服务。本地Service在应用内部,和activity之间没有交互,远程Service可以被其他应用访问,比如天气预报,还可以和用户进行交互和一些数据上的交换。
配置文件
<service android:name=".MyService"></service>
布局
<Button
android:id="@+id/btn_open"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/btn_show"
android:text="Toast"
android:layout_toRightOf="@+id/btn_open"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="show"
/>
java代码
activity:
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
private Button btn_open;
private boolean status=false;
private Intent intent;
private MyService.MyBinder binder;//Binder类
ServiceConnection serviceConnection= new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
binder= (MyService.MyBinder) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(MainActivity.this, "Service Disconnected", Toast.LENGTH_SHORT).show();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent=new Intent(this,MyService.class);
btn_open= (Button) findViewById(R.id.btn_open);
btn_open.setText("open ");
btn_open.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!status){
btn_open.setText("close");
//绑定远程service
bindService(intent,serviceConnection, Service.BIND_AUTO_CREATE);
status=true;
}else{
btn_open.setText("open");
//解绑远程service
unbindService(serviceConnection);
status=false;
}
}
});
}
//btn_show的点击事件
public void show(View v){
Toast.makeText(MainActivity.this, ""+binder.getCount(), Toast.LENGTH_SHORT).show();
}
}
Service:
注意:onStartCommand()方法只会在用户用startService()启动服务才会调用,bindService()则不会。两者启动服务的生命周期如下图所示:
所以如果使用binderService()方法开启服务。请不要在onStartCommand()方法码相关业务。
其次,Service生命周期还有一个特殊的地方—如果Service已经由某个客户端通过startService()启动过,接下来其他用户通过bindService()绑定该Service,再调用unbindService(),再bindService()绑定,这个过程Service的生命周期是:onCreate()-onStartCommand()-onBind()-onUnbind()(返回true)-onRebind();
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
public class MyService extends Service {
int count;
boolean quit=false;
MyBinder myBinder=new MyBinder();
public class MyBinder extends Binder {
public int getCount(){
return count;
}
}
//必须要实现此方法,IBinder对象用于交换数据
@Nullable
@Override
public IBinder onBind(Intent intent) {
return myBinder;
}
@Override
public void onCreate() {
play();
Log.e("TAG","create");
}
//在activity中只有startService()才会调用此方法
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("TAG","start");
return super.onStartCommand(intent, flags, startId);
}
//封装播放
private void play() {
new Thread(){
@Override
public void run() {
while(!quit) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count++;
}
}
}.start();
}
//service 结束绑定调用
@Override
public boolean onUnbind(Intent intent) {
Log.e("TAG","unbinded");
return true;
}
//service被关闭之前调用
@Override
public void onDestroy() {
super.onDestroy();
quit=true;
Log.e("TAG","destoryed");
}
}