前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android多进程4-需要注意的地方

Android多进程4-需要注意的地方

作者头像
随心助手
发布2019-10-14 23:13:09
6830
发布2019-10-14 23:13:09
举报
文章被收录于专栏:nginx遇上redisnginx遇上redis

有一点一定要记住:进程间的内存空间是不可见的。从而,开启多进程后,我们需要面临这样几个问题:

1.Application的多次重建

Manifest文件如上面提到的,定义了两个类:ProcessTestActivity和ProcessTestService,我们只是在Activity的onCreate方法中直接启动了该Service,同时,我们自定义了自己的Application类。代码如下:

代码段1:

代码语言:javascript
复制
public class MyApplication extends Application {
    public static final String TAG = "viclee";
    @Override
    public void onCreate() {
        super.onCreate();
        int pid = android.os.Process.myPid();
        Log.d(TAG, "MyApplication onCreate");
        Log.d(TAG, "MyApplication pid is " + pid);
    }}

代码段2:

代码语言:javascript
复制
publicclass ProcessTestActivity extends Activity {

    public final static String TAG ="viclee";

    @Override
    protected void onCreate(BundlesavedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_process_test);
        Log.i(TAG, "ProcessTestActivityonCreate");
        this.startService(new Intent(this,ProcessTestService.class));

    }}

代码段3:

代码语言:javascript
复制
publicclass ProcessTestService extends Service {

    public static final String TAG ="viclee";

    @Override
    public void onCreate() {
        Log.i(TAG, "ProcessTestServiceonCreate");
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }} 

执行代码打印日志:

我们发现MyApplication的onCreate方法调用了两次,分别是在启动ProcessTestActivity和ProcessTestService的时候,而且我们发现打印出来的pid也不相同。由于通常会在Application的onCreate方法中做一些全局的初始化操作,它被初始化多次是完全没有必要的。出现这种情况,是由于即使是通过指定process属性启动新进程的情况下,系统也会新建一个独立的虚拟机,自然需要重新初始化一遍Application。那么怎么来解决这个问题呢?

下面给出解决方案:

思路:判断是否为主进程,只有主进程的时候才执行下面的操作

代码语言:javascript
复制
StringprocessName = this.getProcessName();//判断进程名,保证只有主进程运行if(!TextUtils.isEmpty(processName)&&processName.equals(this.getPackageName())){
    //在这里进行主进程初始化逻辑操作

   Log.i(">>>>>>","oncreate");}

获取进程名的方法,这个方法是效率最好的:

代码语言:javascript
复制
publicstatic String getProcessName() {
        try {
            File file = newFile("/proc/" + android.os.Process.myPid() + "/" +"cmdline");
            BufferedReader mBufferedReader =new BufferedReader(new FileReader(file));
            String processName =mBufferedReader.readLine().trim();
            mBufferedReader.close();
            return processName;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }}

2. 静态成员的失效

将之前定义的Activity和Service的代码进行简单的修改,代码如下:

代码段1:

代码语言:javascript
复制
publicclass ProcessTestActivity extends Activity {

    public final static String TAG ="viclee";

    public static boolean processFlag = false;

    @Override
    protected void onCreate(BundlesavedInstanceState) {
        super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_process_test);
        processFlag = true;

        Log.i(TAG, "ProcessTestActivityonCreate");

        this.startService(new Intent(this,ProcessTestService.class));
    }}

代码段2:

代码语言:javascript
复制
publicclass ProcessTestService extends Service {

    public static final String TAG ="viclee";

    @Override
    public void onCreate() {
        Log.i(TAG, "ProcessTestServiceonCreate");
        Log.i(TAG,"ProcessTestActivity.processFlag is " +ProcessTestActivity.processFlag);
    }
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }}

重新执行代码,打印Log :

从上面的代码和执行结果看,我们在Activity中定义了一个标志processFlag并在onCreate中修改了它的值为true,然后启动Service,但是在Service中读到这个值却为false。按照正常的逻辑,静态变量是可以在应用的所有地方共享的,但是设置了process属性后,产生了两个隔离的内存空间,一个内存空间里值的修改并不会影响到另外一个内存空间。

3. 文件共享问题

多进程情况下会出现两个进程在同一时刻访问同一个数据库文件的情况。这就可能造成资源的竞争访问,导致诸如数据库损坏、数据丢失等。在多线程的情况下我们有锁机制控制资源的共享,但是在多进程中比较难,虽然有文件锁、排队等机制,但是在Android里很难实现。解决办法就是多进程的时候不并发访问同一个文件,比如子进程涉及到操作数据库,就可以考虑调用主进程进行数据库的操作。

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-19,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 nginx遇上redis 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.Application的多次重建
  • 2. 静态成员的失效
  • 3. 文件共享问题
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com