- 通過Intent 中附加 extras 來傳遞信息
- 通過共享文件的方式來共享數據
- 通過Binder 方式來跨進程通信
- 通過ContentProvider 跨進程通信
- 通過 Socket 網絡通信實現數據傳遞
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.example.yhadmin.aidldemo"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!--未指定 process 屬性,則默認運行在默認進程中,進程名爲包名-->
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- : 的含義是指在當前的進程名前附加上當前的包名,以 : 開頭的進程屬於當前應用的私有進程,其他應用的
組件不可以和它跑在同一個進程中,不以 : 開頭的進程屬於全局進程,其他應用通過 ShareUID 方式可以和
它跑在同一進程中
-->
<activity
android:name=".SecondActivity"
android:configChanges="screenLayout"
android:label="@string/app_name"
android:process=":remote">
</activity>
<!--聲明瞭完整的進程名,不會附加包名信息-->
<activity android:name=".ThirdActivity"
android:configChanges="screenLayout"
android:label="@string/app_name"
android:process="com.example.yhadmin.aidldemo.remote">
</activity>
</application>
</manifest>
MainActivity
public class MainActivity
extends AppCompatActivity
{
private static final String TAG = "MainActivity";
private IBookManager.Stub mBookManager;
private IBinder.DeathRecipient mDeathRecipient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button secondBtn = findViewById(R.id.second);
Button third = findViewById(R.id.third);
secondBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SecondActivity.acrtionStart(MainActivity.this);
}
});
third.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ThirdActivity.acrtionStart(MainActivity.this);
}
});
}
@Override
protected void onResume() {
super.onResume();
new Thread(new Runnable() {
@Override
public void run() {
User user = new User(1, "Hello world", false);
File file = new File(getExternalCacheDir().getPath(),"test.text");
ObjectOutputStream objectOutputStream = null;
try {
objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));
objectOutputStream.writeObject(user);
Log.d(TAG, "PERSIST USER:" + user);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (objectOutputStream!=null)
objectOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
SecondActivity
public class SecondActivity
extends AppCompatActivity
{
private static final String TAG = "MainActivity";
public static void acrtionStart(Context context){
context.startActivity(new Intent(context,SecondActivity.class));
}
private User mUser;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
recoverFromFile();
}
private void recoverFromFile() {
new Thread(new Runnable() {
@Override
public void run() {
File file = new File(getExternalCacheDir().getPath(),"test.text");
ObjectInputStream objectInputStream=null;
try {
objectInputStream = new ObjectInputStream(new FileInputStream(
file));
mUser = (User) objectInputStream.readObject();
Log.d(TAG,"recover user:"+mUser);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally {
try {
if (objectInputStream!=null)
objectInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
Log 日誌
通過它可以再不同進程中傳遞對象,在Message 中放入我們需要傳遞的數據,就可以輕鬆實現數據的進程間傳遞,是一種輕量級的 IPC 方案,它的底層是AIDL,如下是 Messenger 的構造函數:
/**
* Create a new Messenger pointing to the given Handler. Any Message
* objects sent through this Messenger will appear in the Handler as if
* {@link Handler#sendMessage(Message) Handler.sendMessage(Message)} had
* been called directly.
*
* @param target The Handler that will receive sent messages.
*/
//關聯的 Handler 會接收到發送的消息
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
/**
* Create a Messenger from a raw IBinder, which had previously been
* retrieved with {@link #getBinder}.
*
* @param target The IBinder this Messenger should communicate with.
*/
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
- 在服務端創建一個 Service 來處理客戶端的連接請求,同時創建一個 Handler 並通過它來創建一個 Messenger 對象,然後在 Service 的 onBind 方法中返回這個Messenger 對象底層 Binder 即可
- 綁定服務端的 Service,綁定成功後用服務端返回的 IBinder 對象創建一個 Messenger, 通過這個Messenger 就可以向服務端發送消息了,發消息類型爲Message 對象,如果需要服務端能夠迴應客戶端,就和服務的一樣,還需要創建一個 Handler 並創建一個新的 Messenger 對象,並把這個 Messenger 對象通過 Message 的 replyTo 參數傳遞給服務端,服務端通過這個 replyTo 參數就可以迴應客戶端了
public class MainActivity
extends AppCompatActivity
{
private static final String TAG = "MainActivity";
private Messenger mService;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//創建 Messenger 對象
mService = new Messenger(service);
//創建消息載體 Message 對象
Message msg = Message.obtain(null, MyConstants.MSG_FROM_CLIENT);
//跨進程通信數據載體
Bundle data = new Bundle();
data.putString("msg","hello, this is client.");
//msg 裝載 Bundle 數據
msg.setData(data);
try {
//Messenger 發送消息
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button secondBtn = findViewById(R.id.second);
Button third = findViewById(R.id.third);
secondBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, MessengerService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
});
}
@Override
protected void onDestroy() {
unbindService(mConnection);
super.onDestroy();
}
}
public class MessengerService
extends Service
{
private static final String TAG = "MessengerService";
//構建 MessengerHandler 處理客戶端發送的消息,並從消息中去除客戶端發送來的文本信息
private static class MessengerHandler
extends Handler
{
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MyConstants.MSG_FROM_CLIENT:
Log.i(TAG,
"receive msg from Client:" + msg.getData()
.get("msg"));
break;
default:
super.handleMessage(msg);
break;
}
}
}
//通過 MessengerHandler 構建 Messenger 對象,關聯 MessengerHandler
private final Messenger mMessenger = new Messenger(new MessengerHandler());
@Override
public IBinder onBind(Intent intent) {
//返回 Messenger 的 Binder 對象
return mMessenger.getBinder();
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.example.yhadmin.aidldemo"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!-- 未指定 process 屬性,則默認運行在默認進程中,進程名爲包名 -->
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!--
: 的含義是指在當前的進程名前附加上當前的包名,以 : 開頭的進程屬於當前應用的私有進程,其他應用的
組件不可以和它跑在同一個進程中,不以 : 開頭的進程屬於全局進程,其他應用通過 ShareUID 方式可以和
它跑在同一進程中
-->
<activity
android:name=".SecondActivity"
android:configChanges="screenLayout"
android:label="@string/app_name"
android:process=":remote">
</activity>
<!-- 聲明瞭完整的進程名,不會附加包名信息 -->
<activity
android:name=".ThirdActivity"
android:configChanges="screenLayout"
android:label="@string/app_name"
android:process="com.example.yhadmin.aidldemo.remote">
</activity>
<!-- 進程名爲包名:MessengerService -->
<service
android:name=".MessengerService"
android:process=":MessengerService"
android:enabled="true"
android:exported="true">
</service>
</application>
</manifest>
log 日誌:
public class MainActivity
extends AppCompatActivity
{
private static final String TAG = "MainActivity";
private Messenger mService;
private static class MessengerHander extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MyConstants.MSG_FROM_SERVICE://接收服務端發送的消息
Log.i(TAG,
"receive msg from Client:" + msg.getData()
.get("reply"));
break;
default:
super.handleMessage(msg);
break;
}
}
}
private Messenger mGetReplyMessenger = new Messenger(new MessengerHander());
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
/**
* Create a Messenger from a raw IBinder, which had previously been
* retrieved with {@link #getBinder}.
*
* @param target The IBinder this Messenger should communicate with.
*/
//從服務端獲取 Binder 對象,然後創建 Messenger 對象,屬於服務端?
mService = new Messenger(service);
//創建消息載體 Message 對象
Message msg = Message.obtain(null, MyConstants.MSG_FROM_CLIENT);
//跨進程通信數據載體
Bundle data = new Bundle();
data.putString("msg","hello, this is client.");
//msg 裝載 Bundle 數據
msg.setData(data);
//將這個信使存儲在msg的replyTo中,給服務端發消息用
msg.replyTo = mGetReplyMessenger;
try {
//Messenger 發送消息
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button secondBtn = findViewById(R.id.second);
Button third = findViewById(R.id.third);
secondBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, MessengerService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
});
third.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ThirdActivity.acrtionStart(MainActivity.this);
}
});
}
@Override
protected void onDestroy() {
unbindService(mConnection);
super.onDestroy();
}
}
public class MessengerService
extends Service
{
private static final String TAG = "MessengerService";
//構建 MessengerHandler 處理客戶端發送的消息,並從消息中去除客戶端發送來的文本信息
private static class MessengerHandler
extends Handler
{
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MyConstants.MSG_FROM_CLIENT:
Log.i(TAG,
"receive msg from Client:" + msg.getData()
.get("msg"));
//獲取 msg.replyTo 中的 Messenger,即客戶端發送過來的Messenger
Messenger client = msg.replyTo;
Message relpyMessage = Message.obtain(null, MyConstants.MSG_FROM_SERVICE);
Bundle bundle = new Bundle();
bundle.putString("reply","嗯,你的消息我已經收到,稍後會回覆你。");
relpyMessage.setData(bundle);
try {
client.send(relpyMessage);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
break;
}
}
}
//通過 MessengerHandler 構建 Messenger 對象,關聯 MessengerHandler
private final Messenger mMessenger = new Messenger(new MessengerHandler());
@Override
public IBinder onBind(Intent intent) {
/**
* Retrieve the IBinder that this Messenger is using to communicate with
* its associated Handler.
*
* @return Returns the IBinder backing this Messenger.
*/
//返回 Messenger 的 Binder 對象
return mMessenger.getBinder();
}
}
log 日誌:03-07 10:34:19.875 25823-25823/? I/MessengerService: receive msg from Client:hello, this is client.
03-07 10:34:19.875 25723-25723/com.example.yhadmin.aidldemo I/MainActivity: receive msg from Client:嗯,你的消息我已經收到,稍後會回覆你。
private Messenger mGetReplyMessenger = new Messenger(new MessengerHander());
通過關聯的Handler 獲取 IMessenger 對象private final IMessenger mTarget;
/**
* Create a new Messenger pointing to the given Handler. Any Message
* objects sent through this Messenger will appear in the Handler as if
* {@link Handler#sendMessage(Message) Handler.sendMessage(Message)} had
* been called directly.
*
* @param target The Handler that will receive sent messages.
*/
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
Handler 中的 getIMessenger 方法
final IMessenger getIMessenger() {
synchronized (mQueue) {
if (mMessenger != null) {
return mMessenger;
}
mMessenger = new MessengerImpl();
return mMessenger;//返回Messenger 對象,
}
}
private final class MessengerImpl extends IMessenger.Stub {
public void send(Message msg) {
msg.sendingUid = Binder.getCallingUid();//存儲當前進程的 Uid
Handler.this.sendMessage(msg);//通過Handler 發送消息
}
}
Messenger發送消息//Messenger 發送消息
mService.send(msg);
在源碼中調用的是 MessengerImpl 的 send 方法,最終調用的是Handler 的 sendMessage(msg)方法 /**
* Send a Message to this Messenger's Handler.
*
* @param message The Message to send. Usually retrieved through
* {@link Message#obtain() Message.obtain()}.
*
* @throws RemoteException Throws DeadObjectException if the target
* Handler no longer exists.
*/
public void send(Message message) throws RemoteException {
mTarget.send(message);
}
通過 IBinder 對象構建 Messenger 對象
//從服務端獲取 Binder 對象,然後創建 Messenger 對象,屬於服務端?
mService = new Messenger(service);
源碼:
/**
* Create a Messenger from a raw IBinder, which had previously been
* retrieved with {@link #getBinder}.
*
* @param target The IBinder this Messenger should communicate with.
*/
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
而這個IBinder 對象是通過綁定服務端時,回傳給客戶端的 @Override
public IBinder onBind(Intent intent) {
/**
* Retrieve the IBinder that this Messenger is using to communicate with
* its associated Handler.
*
* @return Returns the IBinder backing this Messenger.
*/
//返回 Messenger 的 Binder 對象
return mMessenger.getBinder();
}
查看源碼可知該IBinder 對象實質上就是通過 IMessenger獲取的
/**
* Retrieve the IBinder that this Messenger is using to communicate with
* its associated Handler.
*
* @return Returns the IBinder backing this Messenger.
*/
public IBinder getBinder() {
return mTarget.asBinder();
}