深入浅析Android应用中的多进程
这篇文章将为大家详细讲解有关深入浅析Android应用中的多进程,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
创新互联是专业的密云网站建设公司,密云接单;提供网站制作、成都网站设计,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行密云网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
android:process
- 应用实现多进程需要依赖于
android:process
这个属性 - 适用元素:Application, Activity, BroadcastReceiver, Service, ContentProvider。
- 通常情况下,这个属性的值应该是”:“开头。表示这个进程是应用私有的。无法在在跨应用之间共用。
- 如果该属性值以小写字母开头,表示这个进程为全局进程。可以被多个应用共用。(文章结尾会探讨这个问题)
一个应用 android:process
简单示例
应用多进程有什么好处
增加App可用内存
在Android中,默认情况下系统会为每个App分配一定大小的内存。比如从最早的16M到后面的32M或者48M等。具体的内存大小取决于硬件和系统版本。
这些有限的内存对于普通的App还算是够用,但是对于展示大量图片的应用来说,显得实在是捉襟见肘。
仔细研究一下,你会发现原来系统的这个限制是作用于进程的(毕竟进程是作为资源分配的基本单位)。意思就是说,如果一个应用实现多个进程,那么这个应用可以获得更多的内存。
于是,增加App可用内存成了应用多进程的重要原因。
独立于主进程
除了增加App可用内存之外,确保使用多进程,可以独立于主进程,确保某些任务的执行和完成。
举一个简单的例子,之前的一个项目存在退出的功能,其具体实现为杀掉进程。为了保证某些统计数据上报正常,不受当前进程退出的影响,我们可以使用独立的进程来完成。
多进程的不足与缺点
数据共享问题
- 由于处于不同的进程导致了数据无法共享内容,无论是static变量还是单例模式的实现。
- SharedPreferences 还没有增加对多进程的支持。
- 跨进程共享数据可以通过Intent,Messenger,AIDL等。
SQLite容易被锁
- 由于每个进程可能会使用各自的SQLOpenHelper实例,如果两个进程同时对数据库操作,则会发生SQLiteDatabaseLockedException等异常。
- 解决方法:可以使用ContentProvider来实现或者使用其他存储方式。
不必要的初始化
- 多进程之后,每个进程在创建的时候,都会执行自己的
Application.onCreate
方法。 - 通常情况下,onCreate中包含了我们很多业务相关的初始化,更重要的这其中没有做按照进程按需初始化,即每个进程都会执行全部的初始化。
- 按需初始化需要根据当前进程名称,进行最小需要的业务初始化。
- 按需初始化可以选择简单的if else判断,也可以结合工厂模式
一些简单的代码示例
获取当前的进程名
private String getCurrentProcessName() { String currentProcName = ""; int pid = android.os.Process.myPid(); ActivityManager manager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE); for (ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) { if (processInfo.pid == pid) { currentProcName = processInfo.processName; break; } } return currentProcName; }
基本的进程初始化类
这个类用来每个进程共用的业务初始化逻辑。
public class AppInitialization { @CallSuper public void onAppCreate(Application application) { Log.i("AppInitialization", "onAppCreate is being executed."); } }
工厂模式的应用
public class AppInitFactory { public static AppInitialization getAppInitialization(String processName) { AppInitialization appInitialization; if (processName.endsWith(":game")) { appInitialization = new GameAppInitialization(); } else if (processName.endsWith(":music")) { appInitialization = new MusicAppInitialization(); } else { appInitialization = new AppInitialization(); } return appInitialization; } static class GameAppInitialization extends AppInitialization { @Override public void onAppCreate(Application application) { super.onAppCreate(application); Log.i("GameAppInitialization", "onAppCreate is being executed."); } } static class MusicAppInitialization extends AppInitialization { @Override public void onAppCreate(Application application) { super.onAppCreate(application); Log.i("MusicAppInitialization", "onAppCreate is being executed."); } } }
具体的调用时的代码
public class MyApplication extends Application{ private static final String LOGTAG = "MyApplication"; @Override public void onCreate() { super.onCreate(); String currentProcessName = getCurrentProcessName(); Log.i(LOGTAG, "onCreate currentProcessName=" + currentProcessName); AppInitialization appInitialization = AppInitFactory.getAppInitialization(currentProcessName); if (appInitialization != null) { appInitialization.onAppCreate(this); } } }
是否需要多进程
判断是否需要多进程,需要视具体情况而定。
内存限制
- 研究内存占用居高不下的原因
- 如果是由内存泄漏导致,尝试解决来降低内存占用
- 如有必要,可以通过配置largeHeap尝试解决
除了内存限制之外,还需要考虑是否真的需要独立于主进程来执行某些操作。
关于android:process的其他问题
在android:process
部分我们提到,如果这个属性值以小写字母开头,那么就是全局的进程,可以被其他应用共用。
所谓的共用,指的是不同的App的组件运行在同一个指定的进程中。
准备条件
受制于Android系统的安全机制,我们需要做到以下两个准备条件才可以。
- 这个应用使用同样的签名
- 两个应用指定同一个
android:sharedUserId
的值
具体示例
第一个App的Manifest文件,AnotherActivity运行在名为droidyue.com的进程中。
第二个App的Manifest文件,SecondActivity运行在名为droidyue.com的进程中。
上面的AnotherActivity和SecondActivity会运行在一个名为droidyue.com的进程中,尽管他们位于不同的App中。
关于深入浅析Android应用中的多进程就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
当前题目:深入浅析Android应用中的多进程
当前链接:http://scyanting.com/article/jgcido.html