Android Service通信(Binder机制)
2018-01-23 本文已影响22人
sunxiaohang
Service是Android四大组件之一,在android开发中占有举足轻重的地位,service通常会开启一个独立的线程用于后台事务的处理,而service与UI线程通行也成了学习android开发的过程中必不可少的环节。
首先我们创建一个Binder类继承自android.os.Binder
里面有两个方法,分别用于设置通信内容和获取Myservice对象。
public class Binder extends android.os.Binder{
public void setData(String data){
MyService.this.data=data;
}
public MyService getService(){
return MyService.this;
}
}
下面是自定义的Myservice对象继承自Service类,并覆写onCreate
onDestory
onBind
方法。
public MyService() extends Service {
@Override
public void onCreate() {
running=true;
super.onCreate();
new Thread(){
@Override
public void run() {
super.run();
int i=0;
while (running){
i++;
String str=i+":"+data;
System.out.println(str);
if(callback!=null){
callback.onDataChange(str);
}
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}
@Override
public void onDestroy() {
running=false;
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return new Binder();
}
}
之后需要创建一个接口用于检测通信消息发生变化的回调接口。
public interface Callback{
void onDataChange(String data);
}
在主UI线程中添加一些按钮并绑定相应的点击事件用于启动和停止服务,以及更行Service数据。用来检测Service是否与UI线程实时通信。
public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {
private Button bindService;
private Button unBindService;
private Button syncData;
private EditText editText;
private MyService.Binder binder;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
bindService = (Button) findViewById(R.id.bindService);
unBindService = (Button) findViewById(R.id.unBindService);
syncData = (Button) findViewById(R.id.syncData);
editText= (EditText) findViewById(R.id.editText);
textView= (TextView) findViewById(R.id.tv_textout);
bindService.setOnClickListener(this);
unBindService.setOnClickListener(this);
syncData.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.bindService:
bindService(new Intent(this, MyService.class), this, Context.BIND_AUTO_CREATE);
break;
case R.id.unBindService:
unbindService(this);
break;
case R.id.syncData:
if(binder!=null){
binder.setData(editText.getText().toString());
}
break;
}
}
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
binder= (MyService.Binder) iBinder;
binder.getService().setCallback(new MyService.Callback() {
@Override
public void onDataChange(String data) {
Message msg=new Message();
Bundle b=new Bundle();
b.putString("data",data);
msg.setData(b);
handler.sendMessage(msg);
}
});
}
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
textView.setText(msg.getData().getString("data"));
}
};
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
}