2 使用Messenger类需要服务与远程进程通信,可以通过Messenger来为服务提供接口,该技术允许不使用ALDL执行进程间通信(IPC)
Handler 是属于 android.os.Handler这个包里面的 要注意
package com.example.think.binder;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.support.annotation.Nullable;
import android.widget.Toast;
import java.util.logging.Handler;
/**
* Created by Think on 2015/8/30.
*/
public class MessengerService extends Service{
static final int HELLO_WORD=1;
class IncomingHandler extends android.os.Handler{
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case HELLO_WORD:
Toast.makeText(getApplicationContext(),"HELLO WORD",Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
}
}
}
final Messenger messenger=new Messenger(new IncomingHandler());
@Nullable
@Override
public IBinder onBind(Intent intent) {
Toast.makeText(getApplicationContext(),"Binding",Toast.LENGTH_SHORT).show();
return messenger.getBinder();
}
}
package com.example.think.binder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
/**
* Created by Think on 2015/8/30.
*/
public class MainActivity extends Activity {
// private LocalService localService;
// private boolean boo=false;
private Messenger messenger=null;
private boolean bound=false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button=(Button)findViewById(R.id.showTime);
final Button button1=(Button)findViewById(R.id.button2);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!bound)return;
Message message=Message.obtain(null,MessengerService.HELLO_WORD,0,0);
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
// button.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// System.out.print("boo"+boo);
// if(boo){
// if(localService==null){
// System.out.println("localService is null");
// }else{
// System.out.println("localService is not null");
// int num=localService.getNum();
// System.out.println("num" + num);
// Toast.makeText(MainActivity.this, "num" + num, Toast.LENGTH_SHORT).show();
// }
// }
// }
// });
}
@Override
protected void onStop() {
super.onStop();
// if(boo){
// unbindService(connection);
// boo=false;
// }
if(bound){
unbindService(connection1);
bound=false;
}
}
@Override
protected void onStart() {
super.onStart();
// Intent intent=new Intent(this,LocalService.class);
// if(boo) bindService(intent,connection, Context.BIND_AUTO_CREATE);
bindService(new Intent(this,MessengerService.class),connection1,Context.BIND_AUTO_CREATE);
}
// private ServiceConnection connection=new ServiceConnection() {
// @Override
// public void onServiceConnected(ComponentName name, IBinder service) {
// LocalService.LocalBinder binder=(LocalService.LocalBinder)service;
// localService=binder.getService();
// boo=true;
// System.out.println("has go to ServiceConnetion");
// }
// @Override
// public void onServiceDisconnected(ComponentName name) {
// boo=false;
// }
// };
private ServiceConnection connection1=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
messenger=new Messenger(service);
bound=true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
messenger=null;
bound=false;
}
};
}
下面介绍aidl进行进程间通讯
简单说就是一个A应用通过隐式意图去绑定B应用的Service然后利用aidl技术将接口回调给A应用这样A应用就可以调用B应用中接口实现的方法了
首先创建一个接口(注意里面不能存在public等修饰符)
String GetStr();
}
eclipse会自动将上面这个接口自动生成一个.java文件在gen目录下
接下来我们看这个类里面的一些重要方法和类
这里的Stub继承了Binder同时实现了我们写的接口所以我们在service中的onBind返回对象时可以直接继承改抽象类
从这个方法的返回值可以很明显看出改方法用于将一个IBinder对象转成我们接口类型所以在A应用中利用ServiceConnection进行绑定服务可以利用这个方法将返回的IBinder转成我们写的接口类型对象从而调用接口中的方法
aidl的协议:要带包名复制
A应用的代码:
public class MainActivity extends ActionBarActivity {
com.ebest.aidl.Toast toast;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn=(Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
Toast.makeText(MainActivity.this, toast.GetStr(), Toast.LENGTH_LONG).show();
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
@Override
protected void onStart() {
super.onStart();
//绑定Service
bindService(new Intent("com.ebest.aidl"), connection, Context.BIND_AUTO_CREATE);
}
//连接类
private ServiceConnection connection=new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
Log.i("666", "onServiceDisconnected");
}
public void onServiceConnected(ComponentName name, IBinder service) {
toast=com.ebest.aidl.Toast.Stub.asInterface(service);
//public static com.ebest.aidl.Toast asInterface(android.os.IBinder obj)
Log.i("666", "onServiceConnected");
}
};
protected void onDestroy() {
//解绑服务
unbindService(connection);
};
}
B应用的主要代码:
public class Myservise extends Service{
@Override
public IBinder onBind(Intent intent) {
return new Mytoat();
}
public class Mytoat extends Stub{
@Override
public String GetStr() throws RemoteException {
return "渣渣";
}
}
}
记得要在清单中注册Service
<service
android:name="com.example.b.Myservise">
<intent-filter >
<action android:name="com.ebest.aidl"/>
</intent-filter>
</service>