抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

Application多次创建

应用每启动一个新的进程就会调用一次onCreate()方法, 像推送sdk之类的是一个独立的进程, 初始化的时候如果放在onCreate()里面有可能出现多次初始化的现象.

解决方案

根据进程名来进行选择初始化.

// 正常情况下, 一个apk启动就会运行到一个进程中, 其进程名就是apk的包名, 所有组件都会运行到这个进程
// 如果需要运行到单独进程中, 需要用到android:process属性
// application也支持android:process属性, 可以修改应用程序的默认进程名
// 使用多线程的原因:
// 1. 分散内存的使用
//   安卓系统对应用进程的占用是有限制的, 一个占用内存越大的进程, 被系统回收的可能性就越高, 所以让一个组件运行到单独进程, 可以减少主进程的内存的占用, 避免OOM问题.
// 2. 实现多模块
//   比如我做的应用大而全, 里面肯定会有很多模块, 比如有地图模块、大图浏览、自定义WebView等等(这些都是吃内存大户), 还会有一些诸如下载服务, 监控服务等等, 一个成熟的应用一定是多模块化的.
// 3. 子进程奔溃, 主进程可以继续工作
//   如果子进程因为某种原因崩溃了, 不会直接导致主程序的崩溃, 可以降低我们程序的崩溃率.    
// 4. 主进程退出, 子进程可以继续工作
//   即使主进程退出了, 我们的子进程仍然可以继续工作, 假设子进程是推送服务, 在主进程退出的情况下, 仍然能够保证用户可以收到推送消息. 
// 5. 实现守护进程
//   如果主线程中的服务要从开机起持续运行, 若由于内存等原因被系统kill掉, 守护进程可以重新启动主线程的服务.
//   通过JNI利用C/C++, 调用fork()方法来生成子进程, 一般开发者会利用这种方法来做一些daemon(守护进程)进程, 来实现防杀保活等效果.
//   还能通过监控进程, 将这个错误上报给系统, 告知他在什么机型、环境下、产生了什么样的Bug, 提升用户体验.
// --------------------------------------------------------------------------
//  如果android:process的值以冒号开头的话, 那么该进程就是私有进程
public class MyApplication extends Application {

    @Override
    public void onCreate() {        
        String processName = getProcessName(this, android.os.Process.myPid());
        if( processName != null ) {
           // 根据进程名称进行判断进行对应的初始化
            if ( processName.equals("com.such_game.x3dgame.test2") ) {
                Log.d("PlatformHelper","Application -- onCreate()");
            }
        }    
        super.onCreate();
    }

    // 获取进程名称的方法
    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;
    }
}

评论