提到进程间通信首先想到就是aidl方式,本文除了介绍该方式外还会介绍通过Messenger实现,看到Messenger很容易想到Message(Messenger核心是通过Message和Handler进程通信),下面分别介绍这两种方式
一、Messenger方式
1、服务端创建Handler,来处理客户端发来的消息
2、通过Handler实例创建Messenger实例
3、在onBind(Intent intent)方法中返回messenger获得的IBinder实例
4、客户端绑定服务回调onServiceConnected方法通过IBinder获得服务端的Messenger实例
5、客户端通过messenger发送消息到服务端
(1)服务端主要代码:
public class MyService extends Service { private Messenger messenger; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.i("aa", "**收到消息"); Toast.makeText(MyService.this, "收到消息!", Toast.LENGTH_SHORT).show(); } }; public MyService() { } @Override public IBinder onBind(Intent intent) { messenger = new Messenger(mHandler); return messenger.getBinder(); } }
(2)客户端主要代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Messenger messenger; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { messenger = new Messenger(iBinder); } @Override public void onServiceDisconnected(ComponentName componentName) { messenger = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button bt1 = (Button)findViewById(R.id.act_bt1); Button bt2 = (Button)findViewById(R.id.act_bt2); bt1.setOnClickListener(this); bt2.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.act_bt1: Intent intent = new Intent(); intent.setAction("com.huizhong.service"); intent.setPackage("com.huizhong.onedemo");//不设置包名会报异常 bindService(intent, connection, Context.BIND_AUTO_CREATE); break; case R.id.act_bt2: if (messenger == null){ Toast.makeText(MainActivity.this, "请先绑定服务", Toast.LENGTH_SHORT).show(); }else { try { Message message = new Message(); messenger.send(message); } catch (RemoteException e) { e.printStackTrace(); } } break; } } }
注意事项:
a.首先要开启服务端的服务再用客户端绑定。
b.客户端绑定服务要setPackage(String pack)设置服务端服务的包名
二、AIDL方式(双进程保活案例)
1、新建GuardAidl.aidl文件(注意目录结构为aidl/包名/*.aidl),然后clean工程
2、创建本地服务WindowService和新进程服务KeepLiveService
注:android:process值以:开头表示私有进程,以字母开头表示全局进程
3、修改WindowService服务
(1)定义内部类MyBinder继承GuardAidl.Stub,并在onBinder方法中返回该实例
(2)创建ServiceConnection实例,重写onServiceDisconnected方法,在其中开启并绑定保活服务
(3)重写onStartCommand方法,在其中开启并绑定保活服务
4、修改KeepLiveService服务
(1)定义内部类MyBinder继承GuardAidl.Stub,并在onBinder方法中返回该实例
(2)创建ServiceConnection实例,重写onServiceDisconnected方法,在其中开启并绑定本地服务
(3)重写onStartCommand方法,在其中绑定本地服务