Reasons why Android apps need to start multiple processes:
- The memory allocated by a single process is not enough and more memory is needed. The early Android system only allocated 16MB of available memory for a single process application. With the improvement of mobile phone hardware and the improvement of Android system, although more and more memory can be allocated, it can still get more memory by opening multiple processes to process its own APP business.
- For a component running independently, such as a push, its service will start another process
- Run some "invisible person" operations, such as obtaining the user's privacy data, such as preventing the dual daemon from being killed by the user
Open multiple processes
First start a service in the Activity:
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent myServiceIntent = new Intent(MainActivity.this, MyService.class); startService(myServiceIntent); } } public class MyService extends Service { private static final String TAG = "MyService"; @Override public void onCreate() { Log.e(TAG, "onCreate "); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e(TAG, "onStartCommand: "); return START_STICKY; } @Override public void onDestroy() { Log.e(TAG, "onDestroy: "); } @Nullable @Override public IBinder onBind(Intent intent) { return null; } }
Then at androidmanifest Just configure android:process in XML:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.cah.androidtest"> <application android:name=".MyApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.AndroidTest"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MyService" android:process=":remote" /> </application> </manifest>
Remote is subjective. You can also choose other names Instead of the package name of the current application, MyService runs under the name com cah. Android test: in the process of remote. It can also be set to com cah. androidtest. Remote, so MyService runs on COM cah. androidtest. In the process of remote. The two settings are different:
- If the process name starts with:, the new process is private to the application. Components of other applications cannot run in the same process as the new process. When the new process is needed or the service needs to run in the new process, the new process will be created
- If the process name does not start with:, the service will run in a global process named with this name, provided that it has corresponding permissions and will allow components in different applications to run in the same process, so as to reduce the occupation of resources
View process:
Problems caused by opening multiple processes
Opening multiple processes will make the Application run twice:
public class MyApplication extends Application { private static final String TAG = "CAH"; @Override public void onCreate() { super.onCreate(); int pid = android.os.Process.myPid(); Log.e(TAG, "Application.onCreate ==== pid: " + pid); String processNameString = ""; ActivityManager mActivityManager = (ActivityManager) this.getSystemService(getApplicationContext().ACTIVITY_SERVICE); for (ActivityManager.RunningAppProcessInfo appProcess : mActivityManager.getRunningAppProcesses()) { Log.e(TAG, "onCreate: appProcess.pid = " + appProcess.pid); if (appProcess.pid == pid) { processNameString = appProcess.processName; } } if ("com.cah.androidtest".equals(processNameString)) { Log.e(TAG, "onCreate: processName = " + processNameString + " ===work"); } else { Log.e(TAG, "onCreate: processName = " + processNameString + " ===work"); } } } // Application.onCreate ==== pid: 20747 // onCreate: appProcess.pid = 20747 // onCreate: processName = com.cah.androidtest ===work // Application.onCreate ==== pid: 20792 // onCreate: appProcess.pid = 20747 // onCreate: appProcess.pid = 20792 // onCreate: processName = com.cah.androidtest:remote ===work
Both open processes execute the onCreate method. Therefore, it is inappropriate to initialize and transfer data in the Application. The solution is to get the name of each process. If the name of the process is the same as the process name of the Application, carry out the corresponding operation. If it is different, carry out the operation of other processes.
UID and PID identification in Android IPC communication
UID
On Android, a UID identifies an application. The application is assigned a UID at the time of installation, and the UID remains unchanged during the duration of the application on the device. At the beginning of the design, the user ID is given by the user ID of the Android system. If different programs want to access each other, they can only have the same UID, which makes data sharing secure. (different programs also need to have the same signature, and the signature of each company or developer is unique)
Android system began to add multi-user support in Android 4.2. Usually, the first user registered in the system will become the system administrator by default. The settings of different users are different, and the applications and application data installed by different users are also different. However, hardware related settings in the system are common, such as network settings.
After the user switches, the background process running by the previous user can continue to run. In this way, there is no need to interrupt some time-consuming operations in the background when switching users.
PID
PID is the process ID. there can be multiple PIDs in an application. In the Android system, the process ID that has been kill ed is generally not reassigned to the new process. The new process number is generally larger than all previous process numbers.
Process com cah. androidtest:
Process com cah. androidtest:remote:
Process com jiandan. jianeryou: