android 开启多个服务,Android 如何开启多进程?应用是否可以开启N个进程?

开启多进程

首先我们写一个Activity并启动一个service

package com.example.infatuated;

import android.content.Intent;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

Intent MyServiceIntent = new Intent(this, MyService.class);

this.startService(MyServiceIntent);

}

}

service的代码:

package com.example.infatuated;

import android.app.Service;

import android.content.Intent;

import android.os.IBinder;

import android.support.annotation.Nullable;

import android.util.Log;

public class MyService extends Service {

private static final String TAG = "qmsggg";

@Override

public void onCreate() {

Log.i(TAG, "MyService is oncreate");

}

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

Log.i(TAG, "MyProcessActivity is created: ");

return START_STICKY;

}

@Override

public void onDestroy() {

Log.i(TAG, "ODestroy");

}

@Nullable

@Override

public IBinder onBind(Intent intent) {

return null;

}

}

最后我们只需要在AndroidManifest.xml中的配置 android:process就可以了

android:allowBackup="true"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:roundIcon="@mipmap/ic_launcher_round"

android:supportsRtl="true"

android:theme="@style/AppTheme">

需要特别说明的是,android:process=":test" 中的test名字是自定义的,而冒号":"的含义是当前进程名前附加上当前的包名。那么刚刚所创建出的Service的完整进程名就为com.example.infatuated:test.

当然你也可以自己设置完整地进程名,如android:process="com.example.double:test"这便是一种完整地命名方式。

而更重要的是两种命名方式的区别在于:

":"开头的,则这个新的进程,对于这个应用来说是私有的,当它被需要或者这个服务需要在新进程中运行时,这个新进程就会被创建。

如果这个进程的名字是以小写字符开头的,则这个服务将在一个以该名字命名的全局的进程中运行。当然前提是,它要有相应的权限,这将允许它在不同应用中的各个组件可以共享一个进程。从而减少资源的占用。

接下来我们测试验证一下:

public class MyApplication extends Application {

private static final String TAG = "MyApplication";

@Override

public void onCreate() {

super.onCreate();

int pid = android.os.Process.myPid();

Log.i(TAG, "MyApplication is oncreate===="+"pid="+pid);

}

}

日志结果如下:

8e2c5fbfb047

多进程log1.png

可以看到MyApplication的OnCreate方法执行了两次。

分别是在com.example.infatuated和com.example.infatuated:test 两个进程之中各执行了一次。

所以这就衍生出了一个问题,很多开发者都习惯在Application的子类里面去做相应的初始化和数据化存储操作,如果我们开启多个进程让Application的子类各个回调方法都执行多次,这显然是有问题的。

所以,我们应该区分进程,如果是应用进程,则做应用的相关操作,如果是其他进程(在这里是一个服务),就做其他的操作

package com.example.infatuated;

import android.app.ActivityManager;

import android.app.Application;

import android.util.Log;

public class MyApplication extends Application {

private static final String TAG = "MyApplication";

@Override

public void onCreate() {

super.onCreate();

int pid = android.os.Process.myPid();

Log.i(TAG, "MyApplication is onCreate===="+"pid="+pid);

String processnameString = "";

ActivityManager manager =(ActivityManager)this.getSystemService(getApplicationContext().ACTIVITY_SERVICE);

for (ActivityManager.RunningAppProcessInfo appProcessInfo : manager.getRunningAppProcesses()) {

if (appProcessInfo.pid == pid) {

processnameString = appProcessInfo.processName;

Log.i(TAG, "processName=" + processnameString);

}

}

if ("com.example.infatuated:test".equals(processnameString)) {

Log.i(TAG, "processName = " + processnameString);

}

}

8e2c5fbfb047

多进程log2.png

虚拟机上分配了不同的地址空间,修改静态成员只会在自己的进程中有效,同样单例模式也只有在自己的进程中是单例,多个进程就不能称之为单例了,因为很可能多个进程都会存在这个所谓的单例。

于此同时因为SharedPreferences并不支持并发的读写缘故,在多个进程的使用过程中,就可能存在并发的情况,这样SharedPreferences的读写就会变得不可靠。

总结:

所以最后我们可以回答一开始提出的问题,一个应用程序能否开启多个进程,答案是:可以的

然而还有一点需要说明的是,因为多个进程首先会拥有多个Application,数据会被初始化多次,其次进程之间的通信又比较麻烦,再者每一个进程都有其单独的虚拟机,多个进程自然也会消耗较多的内存。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值