背景
一般情况下,一个应用程序就一个进程,这个进程的名称就是应用程序包名。Android 的四大组件在 AndroidManifest 文件中注册的时候,有个属性是 android:process,这里可以指定组件的所处的进程。
一个进程情况下,Application 的 onCreate 方法只会执行一次,但如果应用中采用多进程方式,onCreate 方法会执行多次。
解决方案
获取当前运行进程的名称:
方案1
public static String getProcessName(Context cxt, int pid) {
ActivityManager am = (ActivityManager) cxt.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> runningApps = am.getRunningAppProcesses();
if (runningApps == null) {
return null;
}
for (RunningAppProcessInfo procInfo : runningApps) {
if (procInfo.pid == pid) {
return procInfo.processName;
}
}
return null;
}
方案2
方案二比较快速
public static String getProcessName() {
try {
File file = new File("/proc/" + android.os.Process.myPid() + "/" + "cmdline");
BufferedReader mBufferedReader = new BufferedReader(new FileReader(file));
String processName = mBufferedReader.readLine().trim();
mBufferedReader.close();
return processName;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
然后在 Application 的 onCreate 中获取进程名称并进行相应的判断,例如:
String processName = getProcessName(this, android.os.Process.myPid());
if (!TextUtils.isEmpty(processName) && processName.equals(this.getPackageName())) {//判断进程名,保证只有主进程运行
//主进程初始化逻辑
....
}
完整使用案例
public class MyApplication extends Application {
private static String sCurProcessName = null;
private String processName;
private String packageName;
1. Application的attachBaseContext方法是优先执行的;
2. ContentProvider的onCreate的方法 比 Application的onCreate的方法 先执行;
3. Activity、Service的onCreate方法以及BroadcastReceiver的onReceive方法,是在MainApplication的onCreate方法之后执行的;
4. 调用流程为: Application的attachBaseContext ---> ContentProvider的onCreate ----> Application的onCreate ---> Activity、Service等的onCreate(Activity和Service不分先后);
@Override
protected void attachBaseContext(final Context base) {
super.attachBaseContext(base);
processName = getCurProcessName(base);
packageName = getPackageName();
boolean isMainProcess = !TextUtils.isEmpty(packageName) && TextUtils.equals(packageName, processName);
if (isMainProcess) {
} else if (isPushProcess()) {
} else if (isGameProcess()){
}
}
@Override
public void onCreate() {
super.onCreate();
}
private static String getCurProcessName(Context context) {
if (!TextUtils.isEmpty(sCurProcessName)) {
return sCurProcessName;
}
sCurProcessName = getProcessName(android.os.Process.myPid());
if (!TextUtils.isEmpty(sCurProcessName)) {
return sCurProcessName;
}
try {
int pid = android.os.Process.myPid();
sCurProcessName = getProcessName(pid);
if (!TextUtils.isEmpty(sCurProcessName)) {
return sCurProcessName;
}
//获取系统的ActivityManager服务
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (am == null) {
return sCurProcessName;
}
for (ActivityManager.RunningAppProcessInfo appProcess : am.getRunningAppProcesses()) {
if (appProcess.pid == pid) {
sCurProcessName = appProcess.processName;
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return sCurProcessName;
}
private static String getProcessName(int pid) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("/proc/" + pid + "/cmdline"));
String processName = reader.readLine();
if (!TextUtils.isEmpty(processName)) {
processName = processName.trim();
}
return processName;
} catch (Throwable throwable) {
throwable.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
private boolean isPushProcess() {
return !TextUtils.isEmpty(packageName) && TextUtils.equals("com.ai.test:pushservice", processName);
}
private boolean isGameProcess() {
if (TextUtils.isEmpty(packageName)) {
return false;
}
if (TextUtils.equals("com.ai.test:game", processName)) {
return true;
}
return false;
}
}
版权声明:本文为qq_34681580原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。