一、开发背景
我在开发过程中遇到的问题是这样的。启动app之后,appliction在onCreate中发送了网络请求,打印日志的时候只打印了一次,后台就收到的连接请求却是有两次。一开始以为是哪里多请求了一次,通过debug、Log日志、Toast都只打印一次日志,显示一次日志记录。后来跟同事讨论,使用File文件打印,发现OnCreate是执行了两次。
二、问题分析
打开txt文件,发现打印了多个String字符串。讨论之下才知道,应该是启动一个进程的时候OnCreate,才导致出现多次运行。总结讨论:每个进程对应一个application对象,所以当应用配置了多个进程的时候,application对象的onCreate方法就会执行多次,所以如果在application的onCreate方法中开启轮询或者初始化大量数据时,其实是要做出区分的处理的
三、处理方法
因为每个进程对应一个application对象,为了避免浪费资源,我们可以在application中通过进程的名称来区分具体应该加载哪些资源,执行那些具体逻辑:
例子一:代码:
@Override
public void onCreate() {
super.onCreate();
//对网络连接的重复连接处理
String processName = OsUtil.getProcessName(this, android.os.Process.myPid());
Log.e("processName", "进程名字:" + processName + "/");
if (processName != null) {
boolean defaultProcess = processName.equals("cn.bql.vehiclemounted.vehiclemounteds");
if (defaultProcess) {
Log.e("processName", "初始化启动:"+ processName);
//connectionSocket(); //需要初始化的内容或者网络连接等
} else if (processName.contains(":pushcore")) {
Log.e("processName", "??????");
}else if(processName.contains(":leakcanary")){
Log.e("processName", "启动了OOM检测服务");
} else if(processName.contains(":vitamio")){
Log.e("processName", "启动了视频服务");
}
}
// if (Environment.getExternalStorageState().equals(
// Environment.MEDIA_MOUNTED)) {
// try {
//
// // 获取SDcard路径
// File sdCardDir = Environment
// .getExternalStorageDirectory();
//
// // SDCard目录:/mnt/sdcard
// String sdcardPath = sdCardDir.getAbsolutePath();
// System.out.println("sdCardDir.getAbsolutePath()"
// + sdCardDir.getAbsolutePath());
//
// File file = new File(sdCardDir, FILE_NAME);
// // File file = new File(sdcardPath
// // + File.separator + FILE_NAME);
// // 以指定文件创建RandomAccessFile对象
// RandomAccessFile raf = new RandomAccessFile(file, "rw");
// // 将文件记录指针移动最后
// raf.seek(file.length());
// // 输出文件内容
// raf.write(processName.getBytes()); //打印进程名字
// raf.close();
//
// } catch (Exception e) {
// // TODO: handle exception
// }
// }
}
上面是onCreate里面的代码,下面是工具类:
import android.app.ActivityManager;
import android.content.Context;
import java.util.List;
/**
* Created by Administrator on 2017/2/14.
* 获得进程名字的方法
*/
public class OsUtil {
public static String getProcessName(Context cxt, int pid) {
//获取ActivityManager对象
ActivityManager am = (ActivityManager) cxt.getSystemService(Context.ACTIVITY_SERVICE);
//在运行的进程的
List<ActivityManager.RunningAppProcessInfo> runningApps = am.getRunningAppProcesses();
if (runningApps == null) {
return null;
}
for (ActivityManager.RunningAppProcessInfo procInfo : runningApps) {
if (procInfo.pid == pid) {
return procInfo.processName;
}
}
return null;
}
}
例子二:最近开发中集成了融云聊天,观察其sdk源码可以发现运用了多进程,这就导致application的onCreate方法会执行多次,浪费时间,下面贴出解决方案
onCreate方法这样写:
@Override
public void onCreate() {
super.onCreate();
initIm();
String processName = getCurProcessName(this);
if (!TextUtils.isEmpty(processName)) {
boolean defaultProcess = processName.equals("你的包名");
if (defaultProcess) {
//当前应用的初始化
initBug();
initApp();
}
}
}
获得当前进程的名字
/**
* 获得当前进程的名字
*
* @param context
* @return 进程号
*/
public static String getCurProcessName(Context context) {
int pid = android.os.Process.myPid();
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningAppProcessInfo appProcess : activityManager
.getRunningAppProcesses()) {
if (appProcess.pid == pid) {
return appProcess.processName;
}
}
return null;
}
————————————————
参考:Application的onCreate方法被调用多次的问题