Android IPC程序間通訊(一)檔案共享
IPC程序間通訊簡介
1.在AndroidManifest.xml中宣告元件android:process屬性。
不指定process屬性,則預設執行在主程序中,主程序名字為包名。
android:process = package:remote,將執行在package:remote程序中,屬於全域性程序,其他具有相同shareUID與簽名的APP可以跑在這個程序中。
android:process = :remote ,將執行在預設包名:remote程序中,而且是APP的私有程序,不允許其他APP的元件來訪問。
2.多程序引發的問題
· 靜態成員和單例失效:每個程序保持各自的靜態成員和單例,相互獨立。
· 執行緒同步機制失效:每個程序有自己的執行緒鎖。
· SharedPreferences可靠性下降:不支援併發寫,會出現髒資料。
· Application多次建立:不同程序跑在不同虛擬機器,每個虛擬機器啟動會創
建自己的Application,自定義Application時生命週期會混亂。
綜上,不同程序擁有各自獨立的虛擬機器,Application,記憶體空間,由此引發一系列問題。
3.程序間通訊
Bundle/Intent傳遞資料:
可傳遞基本型別,String,實現了Serializable或Parcellable介面的資料結構。Serializable是Java的序列化方法,Parcellable是Android的序列化方法,前者程式碼量少(僅一句),但I/O開銷較大,一般用於本地檔案存取和網路傳輸;Parcellable稍複雜,但效率高,一般用於記憶體間序列化和反序列化傳輸。
4.優缺點
優點:簡單易用。
缺點:不適合高併發場景,無法做到程序間即時通訊。
適用場景:交換簡單資料,無併發訪問情形和實時性不高的場景。
檔案共享實現自定義物件的存取
1.首先自定義物件需要實現Serializable介面,serialVersionUID保證了序列化和反序列化出來的是相同的兩個物件
package com.example.myfileshare;
import java.io.Serializable;
public class Book implements Serializable {
public static final long serialVersionUID = 123456789123456789L;
private int bookId;
private String bookName;
public Book(int bookId, String bookName) {
this.bookId = bookId;
this.bookName = bookName;
}
//getter和setter方法
}
2.寫入檔案可從檔案讀取的方法,模擬器執行找不到檔案,真機測試順利存取。
//寫入檔案
private void writeToFile() {
new Thread() {
@Override
public void run() {
Book book = new Book(1, "android");
//資料夾路徑
String path = Environment.getExternalStorageDirectory().getPath() + "/cache/";
File f = new File(path);
if (!f.exists()) {
f.mkdirs();
}
//檔案路徑
File cacheFile = new File(path + "book.txt");
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(new FileOutputStream(cacheFile));
//寫入物件
out.writeObject(book);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
//從檔案讀取出物件
private void readFromFile() {
new Thread(new Runnable() {
@Override
public void run() {
String path = Environment.getExternalStorageDirectory().getPath() + "/cache/";
File cacheFile = new File(path + "book.txt");
if (cacheFile.exists()) {
ObjectInputStream in = null;
Book book = null;
try {
in = new ObjectInputStream(new FileInputStream(cacheFile));
book = (Book) in.readObject();
mTextView.setText(book.getBookName());
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
}