多程式通訊系列問題
導讀 | Android中開啟多程式只有一種方法,就是在AndroidManifest.xml中註冊Service、Activity、Receiver、ContentProvider時指定android:process屬性。今天來講解下:多程式通訊方式以及帶來的問題,方便在專案中遇到問題及時的處理; |
- Android的多程式通訊即IPC是指兩個程式之間進行資料交換;
- 程式一般指一個執行單元,在PC和移動裝置中指一個程式或應用;
- 最簡單的情況下,Android應用中只有一個程式,包含一個執行緒,即主執行緒,也叫作UI執行緒,只能在此執行緒更新操作UI;
- 普通情況下是不需要多程式的,但是當應用需要更多的記憶體或者某些特殊的Module或特殊的需求需要執行在多程式條件下;
Android中開啟多程式只有一種方法,就是在AndroidManifest.xml中註冊Service、Activity、Receiver、ContentProvider時指定android:process屬性,例如:
<service android:name=".MyService" android:process=":remote"> </service> <activity android:name=".MyActivity" android:process="com.test.remote2"> </activity>
我們為MyService和MyActivity指定的android:process屬性值有所不同,它們的區別如下:
- :remote:以:開頭是一種簡寫,系統會在當前程式名前附件當前包名,完整的程式名為:com.test:remote,同時以:開頭的程式屬於當前應用的私有程式,其它應用的元件不能和它跑在同一程式;
- com.test.remote2:這是完整的命名方式,不會附加包名,其它應用如果和該程式的ShareUID、簽名相同,則可以和它跑在同一個程式,實現資料共享;
多程式通訊方式主要有以下幾種,它們之間各有優缺點,可根據使用場景選擇選擇:
- AIDL:功能強大,支援程式間一對多的實時併發通訊,並可實現 RPC (遠端過程呼叫);
- Messenger:支援一對多的序列實時通訊, AIDL 的簡化版本;
- Bundle:四大元件的程式通訊方式,只能傳輸 Bundle 支援的資料型別;
- ContentProvider:強大的資料來源訪問支援,主要支援 CRUD 操作,一對多的程式間資料共享,例如我們的應用訪問系統的通訊錄資料;
- BroadcastReceiver:即廣播,但只能單向通訊,接收者只能被動的接收訊息;
- 檔案共享:在非高併發情況下共享簡單的資料;
- Socket:通過網路傳輸資料;
在一個Activity中新建一個靜態變數TEST_STATIC,並在RemoteActivity1中的onStartOtherRemoteActivity方法中自增,之後啟動RemoteActivity2,並在2中列印TEST_STATIC的值;
public static int TEST_STATIC = 21; public void onStartOtherRemoteActivity(View view) { TEST_STATIC++; Log.e(TAG, "onStartOtherRemoteActivity: " + TEST_STATIC); startActivity(new Intent(this, RemoteActivity2.class)); } 結果: // RemoteActivity1 log E/RemoteActivity1: onStartOtherRemoteActivity: 22 // RemoteActivity2 log E/RemoteActivity2: onCreate: 21
並不相同的數值說明在多程式中靜態變數是失效的,同樣的因為靜態變數帶來的問題是單例模式的失效;
原因就是多程式時Android為其他程式分配了一個新的虛擬機器,導致不同的虛擬機器在記憶體上有不同的記憶體地址, 當在新的程式訪問變數時,訪問的其實是這個類在新的虛擬機器中的副本,也就是相當於在:remote和.remote中各有一個RemoteActivity1類,而.remote訪問的那個副本中的TEST_STATIC是沒有進行自增操作的,所以還是會列印出21的初始數值,而在:remote中是自增過的22;
單例模式也是同樣的解釋,當在另一個程式中訪問單例類時,在此程式中其實並沒有進行初始化,所以才會失效;
本質上跟靜態變數類似,在一個程式鎖住的是副本的物件,而在另一個副本中,記憶體都不同,所以肯定是無效的;
SharedPreferences不支援兩個程式同時去執行寫操作,否則會導致一定機率的資料丟失;
SharedPreferences的底層是通過讀寫XML檔案實現的,併發寫很可能導致問題,併發讀寫都不能保證不會出問題;
當一個元件跑在一個新的程式中時,系統給新的程式分配一個新的虛擬機器,就相當於應用又一次的重新啟動,Application作為應用基礎肯定也會被重新建立;
新建Application類,繼承自Application,並在onCreate方法中輸出當前程式的PID:
public class LApplication extends Application { private static final String TAG = "LApplication"; @Override public void onCreate() { super.onCreate(); Log.e(TAG, "onCreate: " + android.os.Process.myPid()); } }
當依次開啟程式後輸出如下:
// Main E/LApplication: onCreate: 16031 // RemoteActivity1 E/LApplication: onCreate: 16127 // RemoteActivity2 E/LApplication: onCreate: 16202
Application被建立多次帶來的問題是,有些時候會需要在Application中初始化些依賴,但是多程式就會隨著Application的建立而重複初始化,可以在Application中設定一些條件跳過重複初始化部分;
// 根據pid獲取程式名 private String getAppName(int pid) { String processName = null; ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE); List list = am.getRunningAppProcesses(); for (ActivityManager.RunningAppProcessInfo info : list) { try { if (info.pid == pid) { processName = info.processName; return processName; } } catch (Exception e) { e.printStackTrace(); return null; } } return null; }
通過PID獲取程式名,與包名做對比,只有跟包名一致時才做一些初始化工作;
原文來自:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2843007/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Android多程式通訊之幾個基本問題Android
- Android 多程式通訊之幾個基本問題Android
- Android 多程式通訊Android
- 多程式問題
- BMS和AFE通訊問題
- Android 元件化之通訊(多模組,多程式)Android元件化
- PHP多程式開發[快問快答系列]PHP
- 5.React中元件通訊問題React元件
- c#多程式通訊,今天,它來了C#
- .NET WebSocket高併發通訊阻塞問題Web
- TCP通訊之經典問題解決TCP
- 程式通訊
- Node.js - 阿里Egg的多程式模型和程式間通訊Node.js阿里模型
- 小程式頁面間通訊——EventChannel(資料量多時)
- ios微信小程式 BLE藍芽通訊開發介面UI卡頓問題iOS微信小程式藍芽UI
- [單刷APUE系列]第十五章——程式間通訊
- Vue的常見問題(七) - 元件的通訊方式Vue元件
- C# UDP通訊 ReceiveAsync() 一直等待問題C#UDP
- Andromeda:適用於多程式架構的元件通訊框架架構元件框架
- Python - 關於類(self/cls) 以及 多程式通訊的思考Python
- docker系列(五):網路通訊Docker
- 面試系列-40個Java多執行緒問題總結面試Java執行緒
- CAsyncSocket TCP協議通訊速度慢的問題(轉)TCP協議
- Vue 中利用 eventBus 進行資料通訊的問題Vue
- 通訊是個大問題,還好我們有方法。
- v-if和v-show區別+元件通訊問題元件
- 使用 Rxjs 解決 Angular Component 之間的通訊問題JSAngular
- Java訊號量實現程式同步問題:水果蘋果香蕉問題Java蘋果
- 畫江湖之 PHP 多程式開發 [程式中如何通訊 共享記憶體]PHP記憶體
- 畫江湖之 PHP 多程式開發 【程式中如何通訊 共享記憶體】PHP記憶體
- 網路通訊單元NU系列
- Android跨程式通訊Android
- PHP程式間通訊PHP
- 程式間通訊——LINUXLinux
- 程式間通訊(Socket)
- 程式間的通訊
- Linux程式間通訊Linux
- [單刷APUE系列]第十七章——高階程式間通訊