添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
<service
android :name= "com.facebook.rti.push.service.FbnsService"
android :label= "@string/app_name"
android :process= ":mqtt" >
</service> 如果 “android:process” 的值不是“:”开头,则系统里有同样名字的进程的话,会放到已存在的同名进程里运行,这样能减小消耗。 如果“android:process”的值是以“:”开头,则启动一个指定名字的进程。

多进程的APP, 进程间的内存是不可见。 另外,多进程的APP还会导致Application.onCreate()函数会被执行多次(每个进程执行一次)。 这种情况会导致很多不必要的错误。下面 举个例子说明一下: 假设APP在 Application.onCreate() 中启动了一个账号数据管理助手 AccountManager ,该类为单例模式,负责对SQLite的账号进行增、删、改等操作。那么,如果这个APP是多进程模式的话,就会执行多次 Application.onCreate() 方法,导致出现多个 AccountManager 实例。可能你会迷惑,这个类明明是单例模式啊,怎么会有多个实例呢?其原因就是进程间内存的不可见性。由于两个进程的内存相互独立,这就会出现多个 AccountManager 实例了。如果每个进程都使用 AccountManager 去对同一个数据进行操作的话,那就会出现 多进程访问共享数据库问题 了。 多进程访问共享数据与多线程访共享问数据是不同的,多线程下还可以通过同步或加锁的方式避免冲突。但是多进程访问数据库就很难解决了,因为 在Android系统中一个进程就是一个VM虚拟机 ,其底层如何对数据库进行操作,我们控制不了(多进程访问同一文件还有解决方法),我们也很难在Java层针对多进程访问数据度进行有效控制,所以 强烈建议避免多进程访问同一数据库。
public static String getProcessName (Context context , int pid){
ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE) ;
List runningApps = am .getRunningAppProcesses() ;
if (runningApps != null && !runningApps.isEmpty()) {
for (ActivityManager.RunningAppProcessInfo procInfo : runningApps) {
if ( procInfo .pid == pid) {
return procInfo .processName ;
}
return null;
}
其中 pid 进程的ID ,可以通过“ android.os.Process.myPid() ”获取。 使用方法如下所示: @Override
public void onCreate () {
String processName = getProcessName( this, android.os.Process. myPid ()) ;
if ( processName != null ) {
boolean defaultProcess = processName .equals(getPackageName()) ;
if ( defaultProcess ) {
initMainProcess() ;
} else if ( processName .contains( ":mqtt" )) {
// TODO- 处理 mqtt 进程的初始化
}
这样一来,我们就可以根据不同的进程来初始化不同的数据,也就可以解决 AccountManager 被实例化多次的问题,进而避免了多进程访问数据库。 如果需求中必须用到多进程访问共享数据库才能解决问题,那么可以考虑使用 ContentProvider

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑