Android开启多进程
2015-12-26 15:58
537 查看
1. 为何要开启多进程
为何开启android应用要开启多进程,主要有以下几点:
单进程所分配的内存不够,需要更多的内存。在早期android系统只为一个单进程的应用分配了16M的可用内存,随着手机的硬件的提升和android系统的改进,虽然可分配内存越来越多,但仍旧可以通过开启多进程来获取更多的内存来处理自己App的业务
独立运行的组件,比如个推,它的服务会另开一个进程。
进行一些“不可告人”的操作的处理,比如双守护进程,来尽力使自己的应用不被系统杀死,或者获取用户的个人信息等其他信息。
2. 开启多进程
首先我们写一个Activity并启动一个service
service的代码:
最后我们只需要在AndroidManifest.xml中的配置 android:process就可以了
这里选择”remote”这个名字是随意主观的,你也可以取其他的名字。冒号“:”的含义是在当前进程名前面附上当前的包名。那么MyService的完整进程名为“com.example.liuwangshu.myprogress:remote”。我们也可以设置 android:process=”com.example.liuwangshu.myprogress.remote”,这是一种完整的命名方式。这两种命名也是有区别的,如果被设置的进程名是以“:”开头的,则这个新的进程对于这个应用来说是私有的,当它被需要或者这个服务需要在新进程中运行的时候,这个新进程将会被创建。如果这个进程的名字是以小写字符开头的,则这个服务将运行在一个以这个名字命名的全局的进程中,当然前提是它有相应的权限。这将允许在不同应用中的各种组件可以共享一个进程,从而减少资源的占用。
现在我们运行程序我们可以看到我们应用开启了两个进程
3. 开启多进程引出的问题
开启多进程确实很简单,但是同时也会带来一些问题,其中一个就是继承Application的类会执行多遍,我没在Application的子类里的oncreat方法中打log,来看看oncreat执行几遍
log中显示MyApplication 的onCreate执行了两次
但是现在很多的开发者都习惯在Application 的子类里去做应用的初始化和数据存储的操作,如果我们开启多个进程而让Application 的子类的各个回调方法都执行多次这显然是不多的,所以我们就应该区分进程,如果是应用的进程则做应用的操作,其他的进程(在这里是一个服务)就做其他的操作。首先我们是知道应用的进程的名字的,我们通过for循环来得到各个进程的名字,如果得到的进程的名字和我们应用进程名相同,我们就应该做应用的操作
来看看Log
总结一下开启多进程所带来的影响:
Application 会执行多次
多线程完全失效
静态成员和单例模式失效
SharedPreferences变得不可靠
第一条我们已经说过了,第二条也无需解释,第三条因为我们开启了多个进程,它们是运行在自己虚拟机上并分配了不同的地址空间,修改静态成员只会在自己的进程中有效,同样单例模式也是只有自己的进程中是单例,多个进程中就不能称之为单例了,因为很可能多个进程都会存在这个所谓的单例。第四条SharedPreferences并不支持并发的读取,多个进程可能存在并发的情况,这样SharedPreferences的读和写都变得不可靠。
为何开启android应用要开启多进程,主要有以下几点:
单进程所分配的内存不够,需要更多的内存。在早期android系统只为一个单进程的应用分配了16M的可用内存,随着手机的硬件的提升和android系统的改进,虽然可分配内存越来越多,但仍旧可以通过开启多进程来获取更多的内存来处理自己App的业务
独立运行的组件,比如个推,它的服务会另开一个进程。
进行一些“不可告人”的操作的处理,比如双守护进程,来尽力使自己的应用不被系统杀死,或者获取用户的个人信息等其他信息。
2. 开启多进程
首先我们写一个Activity并启动一个service
[code]public class MyProcessActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_process); Intent myServiceIntent=new Intent(MyProcessActivity.this,MyService.class); this.startService(myServiceIntent); } }
service的代码:
[code]public class MyService extends Service { private static final String TAG = "wangshu"; @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,"OnDestory"); } @Override public IBinder onBind(Intent arg0) { return null; } }
最后我们只需要在AndroidManifest.xml中的配置 android:process就可以了
[code]<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.liuwangshu.myprogress" > <application android:allowBackup="true" android:name=".MyApplication" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme" > <activity android:name=".MyProcessActivity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MyService" android:label="@string/app_name" android:process=":remote"> </service> </application> </manifest>
这里选择”remote”这个名字是随意主观的,你也可以取其他的名字。冒号“:”的含义是在当前进程名前面附上当前的包名。那么MyService的完整进程名为“com.example.liuwangshu.myprogress:remote”。我们也可以设置 android:process=”com.example.liuwangshu.myprogress.remote”,这是一种完整的命名方式。这两种命名也是有区别的,如果被设置的进程名是以“:”开头的,则这个新的进程对于这个应用来说是私有的,当它被需要或者这个服务需要在新进程中运行的时候,这个新进程将会被创建。如果这个进程的名字是以小写字符开头的,则这个服务将运行在一个以这个名字命名的全局的进程中,当然前提是它有相应的权限。这将允许在不同应用中的各种组件可以共享一个进程,从而减少资源的占用。
现在我们运行程序我们可以看到我们应用开启了两个进程
3. 开启多进程引出的问题
开启多进程确实很简单,但是同时也会带来一些问题,其中一个就是继承Application的类会执行多遍,我没在Application的子类里的oncreat方法中打log,来看看oncreat执行几遍
[code]public class MyApplication extends Application { private static final String TAG = "wangshu"; @Override public void onCreate() { super.onCreate(); int pid = android.os.Process.myPid(); Log.i(TAG, "MyApplication is oncreate===="+"pid="+pid); } }
log中显示MyApplication 的onCreate执行了两次
但是现在很多的开发者都习惯在Application 的子类里去做应用的初始化和数据存储的操作,如果我们开启多个进程而让Application 的子类的各个回调方法都执行多次这显然是不多的,所以我们就应该区分进程,如果是应用的进程则做应用的操作,其他的进程(在这里是一个服务)就做其他的操作。首先我们是知道应用的进程的名字的,我们通过for循环来得到各个进程的名字,如果得到的进程的名字和我们应用进程名相同,我们就应该做应用的操作
[code]public class MyApplication extends Application { private static final String TAG = "wangshu"; @Override public void onCreate() { super.onCreate(); int pid = android.os.Process.myPid(); Log.i(TAG, "MyApplication is oncreate====" + "pid=" + pid); String processNameString = ""; ActivityManager mActivityManager = (ActivityManager) this.getSystemService(getApplicationContext().ACTIVITY_SERVICE); for (ActivityManager.RunningAppProcessInfo appProcess : mActivityManager.getRunningAppProcesses()) { if (appProcess.pid == pid) { processNameString = appProcess.processName; Log.i(TAG, "processName=" + processNameString); } } if ("com.example.liuwangshu.myprogress".equals(processNameString)) { Log.i(TAG, "processName=" + processNameString + "-----work"); } else { Log.i(TAG, "processName=" + processNameString + "-----work"); } } }
来看看Log
总结一下开启多进程所带来的影响:
Application 会执行多次
多线程完全失效
静态成员和单例模式失效
SharedPreferences变得不可靠
第一条我们已经说过了,第二条也无需解释,第三条因为我们开启了多个进程,它们是运行在自己虚拟机上并分配了不同的地址空间,修改静态成员只会在自己的进程中有效,同样单例模式也是只有自己的进程中是单例,多个进程中就不能称之为单例了,因为很可能多个进程都会存在这个所谓的单例。第四条SharedPreferences并不支持并发的读取,多个进程可能存在并发的情况,这样SharedPreferences的读和写都变得不可靠。
相关文章推荐
- android system.exit(0)后会重启
- Android编程开发实现带进度条和百分比的多线程下载
- 如何在android studio中配置lib
- Android使用SharedPreferences保存数组
- Android 正确修改项目包名而不报错的方法...
- Android中自定义SeekBar的背景颜色,进度条颜色,以及滑块的图片
- Android greenDao 使用教程(一)源码编译与使用
- android:windowSoftInputMode属性详解
- 【风马一族_Android】android的新发现
- 学习笔记1: Activity 生命周期
- Android之获取手机上已安装的所有的应用程序的信息,并判断是否安装了某应用程序(系统程序或非系统应用程序判断)
- android——fragment长时间home或者锁屏java.lang.IllegalArgumentException:No view found for id for....
- android——拍照,相册图片剪切其实就这么简单
- android——生成或者下载的图片在相册中找不到
- android——fragment详解
- Android:弄明白Touch事件分发机制
- android——背景颜色渐变(梯度变化)
- android 无线调试
- android——字体颜色跟随状态改变
- (转)android多国语言适配