前言
在我们的开发中,如果使用了第三方库比如网络请求库LiteHttp,图片加载库universalimageloader等等都需要在Application里面进行初始化,可是当我们在使用多进程的时候Application会被重新创建,相当于有多少个进程就初始化多少次,所以我们需要根据进程的不同来进行不同的初始化才行。
实现
public class MyApplication extends Application {
private final static String PROCESS_NAME = 进程名(就是应用包名);
private static MyApplication myApplication = null;
public static MyApplication getApplication() {
return myApplication;
}
/**
* 判断是不是UI主进程,因为有些东西只能在UI主进程初始化
*/
public static boolean isAppMainProcess() {
try {
int pid = android.os.Process.myPid();
String process = getAppNameByPid(MyApplication.getApplication(), pid);
if (TextUtils.isEmpty(process)) {
return true;
} else if (PROCESS_NAME.equalsIgnoreCase(process)) {
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
return true;
}
}
/**
* 根据Pid得到进程名
*/
public static String getAppNameByPid(Context context, int pid) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (android.app.ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
if (processInfo.pid == pid) {
return processInfo.processName;
}
}
return ;
}
@Override
public void onCreate() {
super.onCreate();
myApplication = this;
if (isAppMainProcess()) {
//do something for init
}
}
}
大致原理就是获取当前进程的包名,然后根据进程的不同进行初始化。
补充
根据进程pid获取进程名有多种方法,下面贴出一种不同于上面的实现方式:
/**
* 获取进程号对应的进程名
*
* @param pid 进程号
* @return 进程名
*/
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 exception) {
exception.printStackTrace();
}
}
return null;
}
在上面我们通过ActivityManager#getRunningAppProcesses获取了当前正在运行的进程信息(高版本只能获取到自己的进程信息),RunningAppProcessInfo除了pid,processName两个字段,还有一个importance字段比较重要,取值如下
/** @hide */
@IntDef(prefix = { "IMPORTANCE_" }, value = {
IMPORTANCE_FOREGROUND,
IMPORTANCE_FOREGROUND_SERVICE,
IMPORTANCE_TOP_SLEEPING,
IMPORTANCE_VISIBLE,
IMPORTANCE_PERCEPTIBLE,
IMPORTANCE_CANT_SAVE_STATE,
IMPORTANCE_SERVICE,
IMPORTANCE_CACHED,
IMPORTANCE_GONE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface Importance {}
当importance为IMPORTANCE_FOREGROUND,表示当前进程在前台!!!!通过这个方法,我们可以很容判断App是否在前台,只需要判断ui进程的importance即可!!!!
本文转自:http://blog.csdn.net/wei1583812/article/details/53395234