多程式通訊系列問題
導讀 | 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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 多程式問題
- distinct 多列問題 group by 解決
- 關於陣列的物件獲取及排序問題/小程式的多層頁面返回問題陣列物件排序
- 程式間通訊系列--管道
- 關於 多程式epoll 與 “驚群”問題
- 面試題:陣列按列排序的問題面試題陣列排序
- Java 物件陣列多屬性條件排序問題(詳解)Java物件陣列排序
- 有趣的CSS題目(6): 全相容的多列均勻佈局問題CSS
- php陣列問題PHP陣列
- 多對多的操作問題
- 如何解決多程式或多執行緒併發的問題執行緒
- 金幣陣列問題陣列
- java陣列的問題Java陣列
- Android 多程式通訊之幾個基本問題Android
- Android多程式通訊之幾個基本問題Android
- C++以多型方式處理陣列可能會遇到的問題C++多型陣列
- 多執行緒問題執行緒
- 多listener 埠的問題
- mysql多版本共存問題MySql
- leetcode題解(陣列問題)LeetCode陣列
- 微軟是如何解決 PC 端程式多開問題的微軟
- python中多程式消費者生產者問題Python
- Android多程式之Binder解綁監聽的問題Android
- js陣列全排列問題JS陣列
- 古老的CSS同高列問題CSS
- 陣列和指標的問題陣列指標
- 多個 Laravel 應用 queue 佇列執行時會互串的問題Laravel佇列
- 使用者和角色多對多問題,物件間關聯處理問題物件
- 小程式 setData 學問多
- 多語言遇到的問題
- sql多參問題解決SQL
- 多OA的分散式問題分散式
- Java程式設計師面試中的多執行緒問題Java程式設計師面試執行緒
- 談談一些有趣的CSS題目(六)–全相容的多列均勻佈局問題CSS
- 關於PHP佇列的問題PHP佇列
- 陣列效能問題分析總結陣列
- vue 陣列和物件渲染問題Vue陣列物件
- Python陣列中求和問題Python陣列