[Android interview questions] Android Framework core interview questions - the difference and connection between Pid & Uid in Android

The difference and connection between Pid&Uid in Android

What do you want to examine with this question?

Examine the concepts and understanding of Pid and Uid in the Android system

How to answer the exam

As we all know, Pid is the process ID, and Uid is the user ID. However, Android is different from computers. Each user of the computer has a Uid. Which user starts the program, the Uid of the program is that user, and every program in Android has a Uid. There is a Uid. By default, Android will assign a common-level Uid to each program that is different from each other. If you use each other to call each other, the Uid can only be the same. This makes the shared data have a certain degree of security. Data cannot be obtained freely between softwares. The same application has only one Uid, so there is no access permission issue between Activities under the application.

PID

The full name of PID in Android is Process Identifier, which comes from Linux. When the process starts, the system will assign a unique identifier to the process. After the process is destroyed, the PID will be recycled by the system, but it is generally not reassigned in Android. The following The process PID will be greater than that of the previous process. However, the same Android application can have multiple PIDs, and it is very convenient to add them. You only need to specify the process name when declaring the class. The code is as follows:

 <activity android:name=".TestActivty" android:process="com.xiaohan.test"/>

It is very convenient to add, but it cannot be used casually, because in the same application (PID), the most communication between programs is designed to be inter-thread communication. Once the PID is independent, it involves inter-process communication, similar to two different applications. , of course, data communication can also be achieved through the above private exposure and permission exposure methods, but the system overhead is relatively large.

UID

UID in Android is generally considered to be User Identifier, which also comes from Linux. But it’s different in Android. Android was originally designed for a single user, so UID is not to distinguish users, but to share data between different programs. Each program in Android has a Uid. By default, Android will assign a common-level Uid to each program that is different from each other. Therefore, if the programs expect to call each other, only the Uid must be the same , which makes the shared data There is a certain degree of security, and data cannot be obtained at will between each software. The same application has only one Uid, so there is no access permission issue between Activities under the application.

UID in Android is used to identify an application. UID is assigned when the application is installed and will not change while the application exists on the phone. An application can only have one uid, and multiple applications can share the same uid using sharedUserId, provided that the signatures of these applications must be the same.

How UID is assigned

When the application starts, or when the phone starts, PackageManagerService will parse the apk and assign a UID to the app. The specific process is as follows (based on Android 11):

In PackageManagerService.java, when the PMS constructor is initialized, a function scanDirTracedLI() will be executed. In scanDirTracedLI(), scanDirLI() will be executed, then scanPackageTracedLI() will be executed, then scanPackageLI() will be executed, and then addForInitLI( will be executed. ), and then execute scanPackageNewLI(). Of course, this process will involve a lot of code details. It is recommended that you study the PKMS part in this chapter. In this scanPackageNewLI function, mSettings.getSharedUserLPw() will be executed to obtain the shared user. If there is no shared user, create a new one. Please see the following code:

SharedUserSetting getSharedUserLPw(String name, int pkgFlags, int pkgPrivateFlags,
		boolean create) throws PackageManagerException {
    
    
	SharedUserSetting s = mSharedUsers.get(name);
	if (s == null && create) {
    
    
		s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
		s.userId = acquireAndRegisterNewAppIdLPw(s); //核心代码
		if (s.userId < 0) {
    
    
			// < 0 means we couldn't assign a userid; throw exception
			throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
					"Creating shared user " + name + " failed");
		}
		Log.i(PackageManagerService.TAG, "New shared user " + name + ": id=" + s.userId);
		mSharedUsers.put(name, s);
	}
	return s;
}

The above code shows that if the SharedUserSetting information is not created for this app and you need to create one, then create one and then call the acquireAndRegisterNewAppIdLPw function to assign it a UID.

private int acquireAndRegisterNewAppIdLPw(SettingBase obj) {
    
    
	// Let's be stupidly inefficient for now...
	final int size = mAppIds.size();
	//code1 从0开始,找到第一个未使用的ID,此处对应之前有应用被移除的情况,复用之前的ID
	for (int i = mFirstAvailableUid; i < size; i++) {
    
    
		if (mAppIds.get(i) == null) {
    
    
			mAppIds.set(i, obj);
			return Process.FIRST_APPLICATION_UID + i;
		}
	}

   //code2 最多只能安装 9999 个应用
	// None left?
	if (size > (Process.LAST_APPLICATION_UID - Process.FIRST_APPLICATION_UID)) {
    
    
		return -1;
	}

	mAppIds.add(obj);
    // code3 可以解释为什么普通应用的UID 都是从 10000开始的
	return Process.FIRST_APPLICATION_UID + size;
}

From the above we can see that the UID assigned to the APP follows the following principles: 1) From code1, we know that the ID can be reused. When an app is uninstalled, its ID will be reused by subsequent apps installed. , 2) From code2, we know that the user ID cannot exceed 19999, which means that the number of apps that can be installed cannot exceed 9999, otherwise the installed app will not have a uid assigned; 3) Each UID is a number greater than Process.FIRST_APPLICATION_UID, That is, they are all greater than 10,000;

The value of UID in Android

In Android, a UID corresponds to an executable program. While the program remains in the Android system, its UID remains unchanged. The concept of sandbox is used in Android to manage programs. Different programs have unique UIDs and PIDs. The UID is used to identify the "resources" they have, including file directories, database access, networks, sensors and logs, etc. Like Linux, they do not affect each other.

Insert image description here

Different applications generally run in different processes, and the "resources" between them cannot be accessed. However, data access between different programs can be achieved through process sharing, mainly for Activity, Service and ContentProvider. The implementation methods are divided into three methods according to the permission exposure level: full exposure, permission prompt exposure and private exposure.

completely exposed

It refers to the implementation through android:exported="true". When declaring Activity, Service or ContentProvider in AndroidMaindfest.xml, setting this attribute to true indicates that the class allows external data access. If the intentFilter attribute is added when declaring, the default exported is true, and it can also be forcibly set to fasle. If no other settings (exported/intentFilter) are made, the default exported is fasle, that is, it is not exposed to the outside world. As shown in the following code:

<activity android:name=".TestActivty" android:exported="true"/>

Permission prompt exposed

When declaring Activity, Service or ContentProvider in AndroidMaindfest.xml, permission is added, indicating that if other applications need to access this class, they need to add the permissions when the class is declared in the application and declare private permissions, as shown below.

<activity android:name=".TestActivty" android:permission="com.xiaohan.permission"/>
//添加访问的权限说明
<uses-permission android:name="com.xiaohan.permission"/>

private exposure

Different from the above two types of exposure methods, if you want different applications to access any data from each other, you need to implement it through sharedUserId + the same set of signatures. Only in this way can they run in the same process (in the same sandbox) and ensure Mutual access to data.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.xiaohan.test"      //应用包名
    android:sharedUserId="com.xiaohan.sharedUID"  //暴露的唯一标识
    android:sharedUserLabel="@string/app_name"  //必须是引入资源文件中的字符串
    android:versionCode="1"
    android:versionName="1.1.0"
    //安装位置,默认在内部目录,还包括auto:自动、  preferExternal:外置SD卡中
    android:installLocation="internalOnly">

Insert image description here

Summarize

Different applications have unique UIDs, and the same UID can have different PIDs;

For data exposure between different PIDs, private exposure and permission exposure can be used, and for different UIDs, complete exposure can be used;

If an application is a system application, it can directly access the application's data without exposing it to other applications.

at last

I have compiled a collection of Android interview questions. In addition to the above interview questions, it also includes [ Java basics, collections, multi-threading, virtual machines, reflection, generics, concurrent programming, Android's four major components, asynchronous tasks and message mechanisms, UI drawing , performance tuning, SDN, third-party framework, design pattern, Kotlin, computer network, system startup process, Dart, Flutter, algorithm and data structure, NDK, H.264, H.265. Audio codec, FFmpeg, OpenMax, OpenCV, OpenGL ES ]
Insert image description here

Friends in need can scan the QR code below to receive all interview questions + answer analysis for free! ! !

Guess you like

Origin blog.csdn.net/datian1234/article/details/133393214