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;
}
}