<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
|
产品答疑