The manifest tag contains content

<manifest xmlns:android="http://schemas.android.com/apk/res/android"// Namespace Android :versionCode="1"// The version number will be overwritten by Gradle. Android :versionName= is not recommended"1.0"// Version name, same as android:sharedUserId="net.loosash.share"// sharedUserId Android :sharedUserLabel="@string/app_name"// Provide the user with a readable tag, value can only use the resource ID Android :installLocation="internalOnly"// The installation location is the default internalOnly: the installation can only be in internal storage. PreferExternal: indicates an installation location on an external storage device, including an internal storage device when the device is unavailable. After the installation, you can move the installation location using the system Settings. Auto: The user can select an internal storage device or an external storage device. package="net.loosash.learnmanifest">... </manifest>Copy the code

SharedUserId Precautions

  • The value of sharedUserId must contain a “.”, otherwise an error will be reported when the package is installed on the phone.
  • Some implementations require the same signature for apKS of the same shareUserId.

3. Understanding sharedUserId

We all know that each Android application runs on a separate VIRTUAL machine to improve the stability of the system. Each application process is created by a separate Linux system user, and the same sharedUserId application belongs to the same Linux user. Resource sharing has a lot of convenience to use. I did a test to see the process using the ADB shell top command. Adb shell top command parsing is included

>adb shell top -h
Usage: top [ -m max_procs ] [ -n iterations ] [ -d delay ] [ -ssort_column ] [-t ] [ -h ] -m num Maximum number of processes to display. No longer show how many processes are intended -n num Updates to show before Withdraw. The refresh frequency-d num  Seconds to waitBetween updates. Refresh interval (default 5 seconds)-scol Column to sort by (cpu,vss,rss,thr). -t Show threads instead of processes. -h Display this displays thread information instead of process informationhelpScreen. Displays help documentsCopy the code

This diagram shows two applications using different sharedUserids

The following image is changed to the same sharedUserId

4. Use the same sharedUserId

The following two application package name respectively net. Loosash. Learnshareduserid application (A), net. Loosash. Learnshareduserid2 application (B) 1, obtain the same sharedUserId application SP Of course, there are other ways to handle SP storage across applications, which will be explained in the SP section. In the getSharePreferences(String name, @preferencesMode int mode) method, mode is context.mode_private. Read SP by getting the Context. A Storage in application

        val preferences = getSharedPreferences("sp", Context.MODE_PRIVATE)
        preferences.edit().putInt(key_test_int, 1024).apply()
        Log.d(tag,"Get inside sp$key_test_intA value of${preferences.getInt(key_test_int,0)}")
Copy the code

B SP is read in the application

        val otherContext = this.createPackageContext("net.loosash.learnshareduserid",Context.CONTEXT_IGNORE_SECURITY)
        val preferences = otherContext.getSharedPreferences("sp", Context.MODE_PRIVATE)
        Log.d(tag,"Get inside sp$key_test_intA value of${preferences.getInt(key_test_int,0)}")
Copy the code

View log output A application

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Copy the code
//        var file = File("/data/data/net.loosash.learnshareduserid/test.txt")
        var file = File("/data/data/net.loosash.learnshareduserid/test_from_b.txt")
        if(! File.exists () {file.createnewfile ()} var input = this.assets."test_from_b.txt"// Add A to BtestA // var input = otherContext.assets. Open ("test.txt")
        var output = FileOutputStream(file)
        val buffer = ByteArray(1024)

        while(input.read(buffer) ! = -1) { output.write(buffer, 0, input.read(buffer)) } input.close() output.close()Copy the code

Error “Permission denied” : failed to access A’s data/data directory

Five, the summary

The same sharedUserId can be set among different applications to unify users on Linux, breaking the sandbox nature among different applications and realizing data and resource sharing.

Pay attention to wechat public number, the latest technology dry goods real-time push