跨进程(同一app不同进程之间通信)——Android自动化测试学习历程
视频地址:http://study.163.com/course/courseLearn.htm?courseId=712011#/learn/video?lessonId=877122&courseId=712011
一、问题:
1、如何做到一个app不同进程通信?
2、多个app通信(不同app)
3、注入事件运行脚本和调用隐藏api
二、一个app不同进程通信:
知识点:
1、Intent、binder
2、Service、Activity
3、Handler、view
4、Messenger、Message、ServiceConnection、IPC(Internal process communication)
5、bundle
6、remote
7、pid
然后接下来说明一下程序实现的原理及过程:
1、定义一个继承自Service的类,使用onBind的生命周期,在服务端定义一个Messenger对象,然后将这个对象的getBinder()通过onBind()方法return给客户端,具体是在绑定的时候会使用到
2、需要给Messenger传递一个Handler对象,需要实现一个继承自Handler类的子类,然后复写HandleMessage()方法,这个就是用来处理从客户端传来的Message,并且根据客户端的内容,做出相应的操作
3、然后在AndroidManifest.xml中注册上面定义的Service类,增加android:process=":remote"
4、然后定义一个客户端程序,如一个Activity类,增加绑定服务和解绑服务的button,然后增加响应时间,主要是调用bindService()方法和unbindService()方法,然后在bindService里面需要使用一个ServiceConnection的对象,需要在定义这个对象的过程中,实现两个方法,分别是onServiceConnected()和onServiceDisconnected(),然后在这里得到Service端的IBinder对象,从而得到Service端的信使,然后通过这个信使,给服务端发消息,服务端就能接收到Msg,之后就会处理这个消息,就是第2步的处理
5、以上实现从客户端到服务端的单向通信,如何实现双向通信?就是在client端依然编写一个Handler类,然后用这个Handler类的对象初始化一个客户端的Messenger对象,然后将本地信使赋值给msg.replyTo,然后服务端Messenger对象.send(msg)就可以将消息发送出去;然后服务端就能获得一个客户端的信使,client和service之间就可以互相通信了。
然后上程序代码:
com.example.twomessengerservice.service中的service程序
package com.example.twomessengerservice.service; import android.app.Service; import android.content.Intent; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.widget.Toast; public class MessengerService extends Service { public static final int SAY_HELLO = 0X1; private Messenger myMessenger = new Messenger(new IncomingHandler()); class IncomingHandler extends Handler{ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub switch(msg.what){ case SAY_HELLO: Toast.makeText(getApplicationContext(), "service的处理", Toast.LENGTH_SHORT).show(); //当需要返回一个值的时候,通过Message来进行传送 Message newmsg = Message.obtain(); newmsg.what = SAY_HELLO; //从msg.reply中获取到客户端的信使 Messenger cMessenger = msg.replyTo; try{ cMessenger.send(newmsg); }catch(RemoteException e){ e.printStackTrace(); } break; default: break; } super.handleMessage(msg); } } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return myMessenger.getBinder(); } }
com.example.twomessengerservice中的client程序:
package com.example.twomessengerservice; import com.example.twomessengerservice.service.MessengerService; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.app.Activity; import android.app.Service; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.util.Log; import android.view.Menu; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity { private Button buttonbind; private Button buttonunbind; boolean isBound = false; Messenger rMessenger = null; Messenger mMessenger = null; private final String tag = "Activity"; class mHandler extends Handler{ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub switch(msg.what){ case MessengerService.SAY_HELLO: Toast.makeText(MainActivity.this, "client的toast",Toast.LENGTH_SHORT).show(); break; default: break; } } } ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub rMessenger = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub rMessenger = new Messenger(service); //获取到service的信使 mMessenger = new Messenger(new mHandler()); //本地信使 sendMessage(); } }; protected void sendMessage() { // TODO Auto-generated method stub Message msg = Message.obtain(null, MessengerService.SAY_HELLO); msg.replyTo = mMessenger; try { rMessenger.send(msg); } catch (RemoteException e) { e.printStackTrace(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); buttonbind = (Button) findViewById(R.id.buttonbind); buttonunbind = (Button) findViewById(R.id.buttonunbind); buttonbind.setOnClickListener(l); buttonunbind.setOnClickListener(l); } View.OnClickListener l = new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub switch(v.getId()){ case R.id.buttonbind: Toast.makeText(getApplicationContext(), "绑定服务", Toast.LENGTH_SHORT).show(); Log.v(tag, "buttonbind"); isBound = bindService(new Intent(MainActivity.this, MessengerService.class), conn, Service.BIND_AUTO_CREATE); Toast.makeText(getApplicationContext(), "接收从服务器端的消息", Toast.LENGTH_SHORT).show(); break; case R.id.buttonunbind: if(isBound = true){ Log.v(tag, "buttonunbind"); Toast.makeText(getApplicationContext(), "解除绑定", Toast.LENGTH_SHORT).show(); unbindService(conn); } break; default: break; } } }; @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
AndroidManifest.xml配置文件:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.twomessengerservice" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.twomessengerservice.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name = ".service.MessengerService"
android:process=":remote"></service> </application> </manifest>
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。