索引:
- Application的生命周期
- Activity的生命周期
- 内存泄漏和内存溢出
- Fragment的懒加载实现
- Android Service、IntentService,Service和组件间通信.
- Activity的onNewIntent
- ContentProvider
- BroadcastReceiver使用总结
- Android消息机制
- Android 事件分发机制
1. Application的生命周期
Application和Activity,Service一样,是Android框架的一个系统组件,当Android程序启动时系统会创建一Application 对象,用来存储系统的一些信息。
Application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。因为它是全局的单例 的,所以在不同的Activity,Service中获得的Application对象都是同一个对象。所以可以通过Application来进行一些,数据传递,数据共享,数据缓存等操作。
在Application中如果保存对象有导致内存泄漏的风险。并且在onCreate中执行耗时操作会直接影响程序的启动时间。
onCreate()
程序创建的时候执行。
onTerminate()
程序终止的时候执行,当程序是被内核终止以便为其他应用程序释放资源,不会被调用。
onLowMemory()
低内存的时候执行。可以用来释放一些不必要的资源来应对后台程序已经终止,前台应用程序内存还不够时的情况。
onConfigurationChanged(Configuration newConfig)
配置改变时触发这个方法。
onTrimMemory(int level)
程序在进行内存清理时执行。
2. Activity的生命周期
onCreate()
->onStart()
->onResume()
->onPause()
->onStop()
->onDestroy()
onPause()
->onCreate()
onPause()
->onResume()
onStop()
->onCreate()
onStop()
->onRestart()
->onStart()
3. 内存泄漏和内存溢出
内存溢出(Out of memory):系统会给每个APP分配内存也就是Heap size值,当APP所需要的内存大于了系统分配的内存,就会造成内存溢出。
内存泄漏(Memory leak):当一个对象不在使用了,本应该被垃圾回收器(JVM)回收,但是这个对象由于被其他正在使用的对象所持有,造成无法被回收的结果。
内存泄漏不会直接引起程序崩溃,但是他是引起内存溢出的因素之一(并不是唯一因素),内存溢出会使程序崩溃。
常见内存泄漏:
1、static
关键字变量生命周期过长
2、单例模式造成。例如单例获取了context
的引用,传入的是activity
的context,在关闭activity时,由于单例还持有context
的引用导致activity
的内存无法被回收。
3、Handler持有Activity引用导致
4、MVP模式的Presenter持有Activity的引用导致
5、实例匿名内部类线程导致。
常见内存溢出:
1、大量图片、音视频处理
2、在主线程处理Bitmap图片
3、由于内存泄漏过多导致内存溢出
4. Fragment的懒加载实现
Fragment生命周期:
onAttach()
->onCreate()
->onCreateView()
->onActivityCreateed()
->onStart()
->onResume()
->onPause()
->onStop()
->onDestroyView()
->onDestroy()
->onDetach()
Fragment的懒加载在Fragment和ViewPager联合使用时应用较多,需要的效果是在当前Fragment显示时再做网络请求加载数据。Fragment的setUserVisibleHint(boolean isVisibleToUser)
会在Fragment显示出来的时候调用,并且在onCreate()
之前。同时提供getUserVisibleHint()
获取Fragment当前是否显示的状态。通过这个状态控制加载,实现懒加载。
5. Android Service、IntentService,Service和组件间通信
Service是一个在后台执行长时间运行操作而不用提供用户界面的应用组件,可由其他组件启动,即使用户切换到其他应用程序,Service 仍然在后台继续运行。
Service有两种启动方式,对应两种生命周期。
启动式:onCreate()
->onStartCommand()
->onDestroy()
绑定式:onCreate()
->onBind()
->onUnbind()
->onDestroy()
IntentService是Service的子类,根据需要处理异步请求(以intent表示)。客户端通过调用startService(Intent) 发送请求,该Service根据需要启动,使用工作线程处理依次每个Intent,并在停止工作时停止自身。它时常用来处理一次性请求的服务。
Service和组件通信:比较方便的是用广播去处理。或者用绑定式的Service,与Activity关联,可以直接调用Service的方法。
6. Activity的onNewIntent
Activity的启动方式有4种。standard、singleTop、singleTask、singleInstance。其中singleTask的设置,在打开栈里存在Activity实例时,不会创建新的实例,而是直接将已有的实例放在栈的最上方
7. ContentProvider
ContentProvider是Android 的四大组件之一,主要用于不同应用之间的的数据共享功能。ContentProvider将数据发布出来,通过ContentResolver(数据调用者)对象调用ContentOrovider的增删改查。
8. BroadcastReceiver使用总结
BroadcastReceiver是Android四大组件之一,能够更容易的实现Android组件间的通信。同时,广播的执行是异步的,并且不要求执行视图可见。
BroadcastReceiver分静态注册和动态注册两种注册方式。静态注册属于常驻型,也就是说,在应用关闭后如果广播信息传来,接受者也会被系统自动运行。而动态注册是随着程序的生命周期绑定的。//静态注册 <receiver android:name=".MyReceiver"> <intent-filter> <action >android:name="android.intent.action.MY_BROADCAST"/> <category >android:name="android.intent.category.DEFAULT" /> </intent-filter> </receiver>
//动态注册 MyReceiver receiver = new MyReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction("android.intent.action.MY_BROADCAST"); registerReceiver(receiver, filter);
同时,广播本身也分为标准广播,有序广播。标准广播发出后,所有接收器都能够接收到,并且接收器无法终止或干扰其他接收器接收。而有序广播在发出的同一刻,只会有一个广播接收器能够接受,并且自行决定是否传递给下一个。
9. Android消息机制
在Android中线程内部或线程之间进行信息交互时进场会使用消息。一个Message经由Handler的发送,MessageQueue的入队,Looper的抽取,又再一次地回到Handler的怀抱中。而绕的这一圈,也正好帮助我们将同步操作变成了异步操作。简单梳理一下:
Message:消息对象,记录消息信息。对于创建Message,推荐使用Message.botain()
,这并不是直接创建一个新的实例,而是先从消息池中查看是可否有可用的Message实例,在没有的时候,才会通过new创建一个新的Message对象。Android在默认情况下,在消息池中实例化10个Message对象。
MessageQueue:消息队列,用来存放Message对象的数据结构,按照“先进先出”的原则存放,并且也不是实际意义的存放,而是将Message对象以链表的方式串联起来。MessageQueue是靠Looper对象进行管理的。一个线程最多只可以拥有一个MessageQueue。我们可以通过Looper.myQueue()获取当前线程中的MessageQueue。
Looper:MessageQueue的管理者,在一个线程中,有Looper则有MessageQueue。在Android中只有主线程默认有Looper对象,如果想要新建的线程有Looper对象,需要调用Looper。prepare()
方法。然后调用Looper.loop()
方法让Looper开始工作。从源码可知,Looper是一个死循环,循环处理MessageQueue中的Message。
Handler: 消息的处理者,通过Handler对象我们可以封装Message对象,然后通过sendMessage(msg)把Message对象添加到MessageQueue中;当MessageQueue循环到该Message时,就会调用该Message对象对应的handler对象的handleMessage()方法对其进行处理。
10. Android 事件分发机制
Touch事件分发中有两个角色:ViewGroup和View。ViewGrou包含
onInterceptTouchEvent、dispatchTouchEvent、onTouchEvent
三个方法而View只有dispatchTouchEvent、onTouchEvent
两个方法。
先看看分发dispatchTouchEvent
。由最顶层Activity的ViewGroup循环子View分发Down事件,如果子View中包含ViewGroup,则循环ViewGroup的子View同样分发Down事件。值得一提的是,在源码中可以看到,ViewGroup是实实在在在做分发事件操作,而View处理的只是自己是否处理接收到的Down事件。在分发过程中,某一个dispatchTouchEvent
的结果返回为true时,顺序分发将会终端,后面的View都将接收不到本次Touch事件。
当某个子View返回true时,会中止Down事件的分发,同时在ViewGroup中记录该子View。接下去的Move和Up事件将由该子View直接进行处理。由于子View是保存在ViewGroup中的,多层ViewGroup的节点结构时,上级ViewGroup保存的会是真实处理事件的View所在的ViewGroup对象:如ViewGroup0-ViewGroup1-TextView
的结构中,TextView返回了true,它将被保存在ViewGroup1中,而ViewGroup1也会返回true,被保存在ViewGroup0中。当Move和UP事件来时,会先从ViewGroup0传递至ViewGroup1,再由ViewGroup1传递至TextView。
现在说说onInterceptTouchEvent
,他最大的作用就是拦截Down事件的分发或是终止Up和Move事件向目标View传递,使得目标View所在的ViewGroup捕获Up和Move事件。
网友评论