作以前大概思路是:基本参考的原理是官方对内存清理时的5个优先级别,制造出一个单独的接收push的进程来放push service。涉及到的问题包括官方的说明、service启动相关原理,一个app两个进程的知识,两个进程间的通讯。html
---------------------mark:T9200,HM1S的代码:NotifyService每5秒发parseReceiver的通知。网络变化主动stop ParseService。C8825增长了解锁时启动NotifyService。java
参考1:微信的两个进程:http://www.cnblogs.com/GIS-Dream/p/3246534.htmlandroid
参考2:android进程间通讯:http://blog.csdn.net/victory08/article/details/8696252git
参考3:Application有一个override方法叫onLowMemoryshell
参考4:官方:http://developer.android.com/guide/components/processes-and-threads.html缓存
参考5:service 的通讯有三种方式:Extending the Binder class;Using a Messenger;Using AIDL安全
Extending the Binder class This is the preferred technique when your service is merely a background worker for your own application. The only reason you would not create your interface this way is because your service is used by other applications or across separate processes.微信
参考6:parse是依赖于gcm的。从manifest能够看出来。国行手机阉割掉的主要是这四个:【1】GoogleServicesFramework.apk(此为必需!要用google服务就得装!)
【2】GoogleContactsSyncAdapter.apk和【3】GoogleCalendarSyncAdapter.apk可根据本身须要安装,不用联系人和日历同步则能够不装,【4】Google Play .APK若是 你想用上google商店----------------这4个APK合起来就是google的服务框架,安装完这几个APK就能够兼容谷歌基本全部的应用。网络
GCM的问题:“先不提4.0以前必须登陆google帐户才能用,gcm容易常常被墙,容易被rom删掉。到达率50%仍是80%仍是90%又如何?不是100%就无法用。即便100% 的android手机都有,偶尔墙一下也受不了。app
参考7:手机360卫士的一些牛B权限:
安全类:1,修改系统设置;2,在其余应用之上进行绘图;3,对正在运行的应用从新排序(移动到前台或者后台reorder other app);4,直接安装应用;5,从新设置外拨电话的路径;
隐私类:1,检索正在运行的应用;
其它类:1,修改安全系统设置;2,关闭其余应用 ;3,删除全部应用缓存数据;4,强制关闭后台应用;5,查阅敏感日志数据;
手机360卫士须要有root权限才能作的是:自启动软件管理,软件权限监控等。全部的权限都定义在android.Manifest类中。ActivityManager类有moveTaskToFront, killBackckProcess,getRunningAppProcess等功能。
参考8:
官网:
A started service can use the startForeground(int, Notification)
API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory. (It is still theoretically possible for the service to be killed under extreme memory pressure from the current foreground application, but in practice this should not be a concern.)
参考9:stack网上一篇讨论:http://stackoverflow.com/questions/7142921/usage-of-androidprocess
首先,关于manifest中的一些细节还须要挖掘一下。http://developer.android.com/guide/topics/manifest/manifest-element.html#uid
而后,官网的Training模块关于多Process的讨论。http://developer.android.com/training/articles/memory.html#MultipleProcesses
还有,官网的Tools模块关于Investigate RAM的介绍
参考10:出现了新的问题,当定义了新的process,新的process会Replicate不少原process的内存过来,致使一个空的service也要15M的内存。而原process内存未减小。
一方面尝试主动去控制新process中的内容,另外一方面尝试主动控制activity资源的在后台时的释放。
参考11:把activity context传递给view,意味着view拥有一个指向activity的引用,进而引用activity占有的资源:view hierachy, resource等。
避免这种内存泄露的方法是避免activity中的任何对象的生命周期长过activity,避免因为对象对 activity的引用致使activity不能正常被销毁。咱们可使用application context。application context伴随application的一辈子,与activity的生命周期无关。application context能够经过Context.getApplicationContext或者Activity.getApplication方法获取。
避免context相关的内存泄露,记住如下几点:
1. 不要让生命周期长的对象引用activity context,即保证引用activity的对象要与activity自己生命周期是同样的
2. 对于生命周期长的对象,可使用application context
3. 避免非静态的内部类,尽可能使用静态类,避免生命周期问题,注意内部类对外部对象引用致使的生命周期变化
【其余的相关事项】
1)在SDK中的DigitalClock Widget ,由于DigitalClock要注册一个observer,因此会用把载上DigitalClock widget的Activity做为那个observer。但在SDK的DigitalClock是有一个Bug的,由于在DigitalClock 的onDetachedFromWindow中是没有unregister 那个observer的。 解决方法是本身写一个DigitalClock。详情请看附上的代码(DigitalClockNew.java)。
2)在SDK中的Toast的function makeText 是要求传一个Context的,但在Toast的代码中,这个Context是会用作callback上。若是是传Activity做为那个 Context的话,那会发生memory leak的问题。解决方法是传 Application Context,而不是ActivityContext。
【如何查看Memory leak的问题】
若是怀疑有memory leak的问题,可先执行那个apk在emulator上,而后在PC上执行adb shell,,而后执行ps,查看你的process 的pid。
在apk上执行有memory leak可疑的动做后,能够作下面的诊断
1. 执行 dumpsys meminfo <pid>
这个指令显示pid的memory资料。注意是 Activity的 数量,若是数量是不断上升,那就是有memory leak。 注意,由于在未执行Gargage Collect前,Activity是不会被释放的。能够在DDMS上执行手动的Gargage Collect。
2. 把process 的memory dump 出来,看memory leak的所在
先执行 chmod 777 /data/misc,而后执行 kill -10 <pid> ,在 /data/misc 上会看到那个pid 的memory leak,(如heap-dump-tm1265266619-pid1673.hprof )
用adb pull ( 如adb pull /data/misc/ heap-dump-tm1265266619-pid1673.hprof 1673.hprof )把这个档案拷回电脑上。
而后,用在PC上执行hprof-conv (如hprof-conv 1673.hprof 1673_a.hprof) 把那个拷回来的hprof转换成 Eclipse Memory Tool 能够支持的格式。
用Eclipse Memory Tool (http://www.eclipse.org/mat/), 打开转换了的memory dump。 在Eclipse Memory Tool 上,按OQL,输入 “select * from instanceof android.app.Activity” , 这个指令能够找因此在系统上是android.app.Activity 的 instance。(详见下图)
若是在object的旁带有“Unknown”的话,那object是能够被Gargage Collect的。要看其余的object是什么缘由不能够被Gargage Collect 的话,能够在那个object上right-click,而后选Path to GC Roots, exclude weak/soft reference 。 (weak 和soft reference 都是能够被VM查到的,因此是能够Gargage Collect的。)
在Path to GC Roots 中,能够看到WidgetManagerHome 是由于Toast中的inner class TN 把 这个WidgetManagerHome抓住了。
(关于查找leaks,参考下这个http://blog.crowdint.com/2013/10/02/fixing-memory-leaks-in-android-applications.html)
==============================================================================
记录:
通过多日的研究,这里简单记录一下。
1,结束service时,不会结束进程。service被杀掉的话,process其实还在。因此能够没必要让service的onDestroy中自动重启。
2,内存紧张时进程被杀掉后,若是service有自动重启,那么整个进程都会执行一次新的启动过程。
2.5,而service没有自动启动的话,内存紧张杀进程还,仍是重启了进程,是否是代码其余地方有处理---此现象只在红米上设置容许自动重启的时候会出现。
3,service被结束后,其Thread变量还在运行,why?
4,onTrimMemory调用可能会很频繁,不可作过多处理
5,没有activity有Service的进程更安全。可是:xxx增长一个进程,会复制不少context环境进去,有可能占用更大的内存
6,叮咚在内存屡次告急(80分)时,还不释放activity,应该是有内存泄露,没法回收。
7,叮咚的MainDingtone有泄露,即便主动调用了finish()方法,仍是没法释放activity的资源
如今要解决的问题是:1,could not construct writer是否是有切换网络的缘由?2,如何主动的把activity资源释放掉?3,尝试监听网络状态,主动关掉parseService,让其自动重启。
注:
已优化:
按键音播放;
其余待优化:
UI缓存跳转的优化;数据模型的抽象共用优化;Activity,View等抽象共用优化;