android會爲每一個apk進程分配一個單獨的空間(好比只能訪問/data/data/本身包名下面的文件),通常狀況下apk之間是禁止相互訪問數據的。經過Shared User id,擁有同一個User id的多個APK能夠配置成運行在同一個進程中.因此默認就是能夠互相訪問任意數據. 也能夠配置成運行成不一樣的進程, 同時能夠訪問其餘APK的數據目錄下的數據庫和文件.就像訪問本程序的數據同樣(使用IPC機制,不一樣進程之間,好比AIDL)。 java
1、使用同一個shareuserid,多個apk運行到同一個進程,實現多個apk之間的數據訪問
實現效果:把A.apk assets目錄下的session.log拷貝到/data/data/A包名/目錄下面 android
A.apk
AndroidManifest.xml 數據庫
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.demo1" android:sharedUserId="com.example" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/title_activity_main" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
B.apk(實現訪問資源而且拷貝)
MainActivity.java(如何訪問assets資源文件請看上一篇http://my.oschina.net/zhoulc/blog/118693) session
package com.example.demo2; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager.NameNotFoundException; import android.view.Menu; import android.view.MenuItem; import android.support.v4.app.NavUtils; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Context context = null; InputStream input = null; OutputStream output = null; try { context = this.createPackageContext("com.example.demo1", Context.CONTEXT_IGNORE_SECURITY); File file = new File("/data/data/com.example.demo1/session.log"); if (!file.exists()) { file.createNewFile(); } input = context.getAssets().open("session.log"); output = new FileOutputStream(file); byte[] buffer = new byte[1024]; int readLength = 0; while((readLength = input.read(buffer)) != -1){ output.write(buffer, 0, readLength); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally{ try { if(input!=null || output!= null){ input.close(); output.close(); input = null; output = null; } } catch (Exception e2) { // TODO: handle exception } } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.demo2" android:versionCode="1" android:versionName="1.0" android:sharedUserId="com.example"> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/title_activity_main" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>A.apk,B.apk使用同一個shareduserid:com.example
2、經過shareduserid來獲取系統權限
(1)在AndroidManifest.xml中添加android:sharedUserId="android.uid.system"
(2)在Android.mk文件裏面添加LOCAL_CERTIFICATE := platform(使用系統簽名)
(3)在源碼下面進行mm編譯
這樣生成的apk可以獲取system權限,能夠在任意system權限目錄下面進行目錄或者文件的建立,以及訪問其餘apk資源等(注意建立的文件(夾)只有建立者(好比system,root除外)擁有可讀可寫權限-rw-------)。
3、擴展
app
系統中全部使用android.uid.system做爲共享UID的APK,都會首先在manifest節點中增長android:sharedUserId="android.uid.system",而後在Android.mk中增長LOCAL_CERTIFICATE := platform。能夠參見Settings等 ide
系統中全部使用android.uid.shared做爲共享UID的APK,都會在manifest節點中增長android:sharedUserId="android.uid.shared",而後在Android.mk中增長LOCAL_CERTIFICATE := shared。能夠參見Launcher等 ui
系統中全部使用android.media做爲共享UID的APK,都會在manifest節點中增長android:sharedUserId="android.media",而後在Android.mk中增長LOCAL_CERTIFICATE := media。能夠參見Gallery等。 this