[转]Android多进程下进行全局初始化操作的正确姿势

/ 0评 / 3

前言

在我们的开发中,如果使用了第三方库比如网络请求库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

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注