1. 程式人生 > >Android IPC程序間通訊(一)檔案共享

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();
    }