Android四大组件
Activity
一个activity就是一个窗口,他们之间用 Intent通信,每个activity都必须在清单文件中配置;
生命周期:
onCreate()——>
onStart()
——>
onResume()——>onPause()——>onStop()——>onDestroy()
启动另一个Activity:第一个
onPause()——>第二个onCreate()——>onStart()——>onResume()——>第一个onStop()
回到第一个Activity:第二个
onPause()——>第一个onRestart()——>onStart()——>onResume()——>第二个Activity onStop()——>onDestroy();
横竖屏切换(默认):切换横屏生命周期会执行一次,切换竖屏会执行两次;
横竖屏切换(设置orientation):各调用一次;
横竖屏切换(设置orientation|keyboardHidden):切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法;
锁屏-开启生命周期:onPause、onStop、onRestart、onStart、onResume;
锁屏生命周期的变化(屏幕改变方向):onPause、onStop、onDestroy、onGreat、onStart、onResume、onPause;
开启生命周期的变化(屏幕改变方向):onResume、onPause、onStop、onDestroy、onGreat、onStart、onResume;
Service
用于在后台完成用户的指定的任务。是运行在主线程中的,如果需要完成耗时操作 可以用IntentService来代替,这样会重新开一个新的线程,IntentService继承Service。
启动方式:
startservice 和bindserverice;
startservice 生命周期:onCreate --> onStart(可多次调用) --> onDestroy。
bindserverice生命周期:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。
区别:
startservice:由其他组件通过startservice()方法启动服务,这导致服务的onStartCommand方法调用,其生命周期与
启动他的无关,并且可以在后台无限期运行,因此服务需要完成任务是需要调动onStopself()方法停
止,或者由其他组件调用onStopService()方法停止;
bindservice:调用者与服务绑定了在一起,一旦调用者退出,服务也会退出;
Broadcast Receiver
用来接收系统的广播,以及接收app发出的广播
注册方式:
动态注册:当注册的activity销毁掉广播也就失效了(谁先注册谁优先级高)
静态注册(清单文件):无需担忧广播接收器是否关闭,只要设备是开启状态,广播就不会关闭;
广播类型:
有序:当receiver执行后,可以传播到下一个receiver,也可以终止广播;可以通过优先级来控制;
无序:完全异步,同一时间会接收到结果,但是不能处理结果;
ContentProvide
使一个应用程序的指定数据来提供给其他数据,可以通过contentprovide存放与获取。只有多个程序共享数据才会用到;
在开发过程中不会直接使用contentprovide对象,而是会用contentResolver对象实现contentprovide类;
contentprovide使用URI唯一来标识数据集,
这里的URI以content://作为前缀,表示该数据由ContentProvider来管理;
Handler机制
事件分发(时间传递)
view绘制流程
1)on measure 测量view大小
2)on layout 确定子view布局(包含子view时用)
3)on draw 实际绘制内容
2)on layout 确定子view布局(包含子view时用)
3)on draw 实际绘制内容
画背景 background.draw(canvas)
绘制自己( onDraw )
绘制 children ( dispatchDraw )
绘制装饰( onDrawScrollBars )
SurfaceView:适用于频繁的迅速刷新 执行在子线程
SurfaceView:适用于频繁的迅速刷新 执行在子线程
图片三级缓存
1)内存缓存 优先加载,速度最快
2)本地缓存 次优先加载 速度稍快
3)网络缓存 最后加载 速度由网络速度决定(浪费流量)
2)本地缓存 次优先加载 速度稍快
3)网络缓存 最后加载 速度由网络速度决定(浪费流量)
Android常用的数据存储方式:①文件存储 ②SharedPreference ③SQLiteDatabase
进程之间的通讯方式:Activity ContentProvider Broadcast Service
布局优化措施: 1)尽可能减少布局的嵌套层级
2)避免过度绘制(不用设置不必要的背景)
3)使用<include>标签复用相同的布局代码
4)使用<merge>标签减少视图层次结构
5)通过<ViewStub>实现 View 的延迟加载
2)避免过度绘制(不用设置不必要的背景)
3)使用<include>标签复用相同的布局代码
4)使用<merge>标签减少视图层次结构
5)通过<ViewStub>实现 View 的延迟加载
屏幕适配的方式:1)适配方式之dp
2)适配方式之dimens
3)适配方式之layout
4)适配方式之java代码适配
5)适配方式之weight权重适配(只能用在线性布局中)
2)适配方式之dimens
3)适配方式之layout
4)适配方式之java代码适配
5)适配方式之weight权重适配(只能用在线性布局中)
glide与Picasso的区别:1)Glide可以加在GIF动态图,而Picasso不能
2)Glide 可以和 Activity 以及 Fragment 的生命周期相互协作
3)加载同样大小的图片,picasso的质量要比glide的质量高,Glide 图片加载进内存时使用的是 RGB_565 的配置,Picasso 则使用 ARGB_8888
2)Glide 可以和 Activity 以及 Fragment 的生命周期相互协作
3)加载同样大小的图片,picasso的质量要比glide的质量高,Glide 图片加载进内存时使用的是 RGB_565 的配置,Picasso 则使用 ARGB_8888
Fragment的生命周期
onAttach -->onGreate --> onGreateView -->onActivityGreated -->onstart -->onReusem -->onPause --> onStop -->onDestroyVIew --> onDestroy --> onDetach
线程池的好处: ThreadPoolExecutor 线程的重用 创建和销毁线程的开销 控制线程中的并发数 对线程的管理
activity被系统回收,如何在此之前保存当前的状态?
重写onSaveInstanceState()方法,会在activity回收之前调用
通过重写onRestoreInstanceState()方法可以从中提取保存好的数据
通过重写onRestoreInstanceState()方法可以从中提取保存好的数据
Get与Post的区别: 1)Get能被缓存,post不能缓存;
2) get能保存书签,post不能保存书签;
3)get对数据有限制(GET方法向URL添加数据 URL的长度是受限制的2048个字符),post无限制;
4)get数据在url中是对所有人可见的,post对所有人不可见;
2) get能保存书签,post不能保存书签;
3)get对数据有限制(GET方法向URL添加数据 URL的长度是受限制的2048个字符),post无限制;
4)get数据在url中是对所有人可见的,post对所有人不可见;
Asynctask:Asynctask是对Thread和Handler进行了封装
onPreExecute : 在主线程中运行
doInBackground : 运行在单独的线程中,可以执行耗时操作,会在onPreExecute执行完后执行
而且会将处理的结果通过publishProgress传递UI线程
onProgressUpdate : 调用publishProgress方法后,就会在UI线程回调此方法。更新界面
onPostExecute : doInBackground的返回值会作为参数传入主线程onPostExecute,更新界面
注意:Asynctask 的实例必须在主线程中创建
Asynctask.excute 必须在主线程中调用 只能执行一次 第二次会报错
怎么让多个AsynTask并行?
DownloadTask downloadTask1 = new DownloadTask();
downloadTask1.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, urls);//传入 THREAD_POOL_EXECUTOR 线程池对象即可
doInBackground : 运行在单独的线程中,可以执行耗时操作,会在onPreExecute执行完后执行
而且会将处理的结果通过publishProgress传递UI线程
onProgressUpdate : 调用publishProgress方法后,就会在UI线程回调此方法。更新界面
onPostExecute : doInBackground的返回值会作为参数传入主线程onPostExecute,更新界面
注意:Asynctask 的实例必须在主线程中创建
Asynctask.excute 必须在主线程中调用 只能执行一次 第二次会报错
怎么让多个AsynTask并行?
DownloadTask downloadTask1 = new DownloadTask();
downloadTask1.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, urls);//传入 THREAD_POOL_EXECUTOR 线程池对象即可
常见异常
内存泄漏:在对象的生命周期本该结束的时候,这个对象还被一系列的引用,会导致内存泄露;
原因:
资源对象没关闭
使用Adapter时,没有使用系统缓存的converView
没有即时调用recycle()释放不再使用的bitmap
使用application的context来替代activity相关的context
广播注册没取消造成内存泄露
Handler应该申明为静态对象, 并在其内部类中保存一个对外部类的弱引用
使用Adapter时,没有使用系统缓存的converView
没有即时调用recycle()释放不再使用的bitmap
使用application的context来替代activity相关的context
广播注册没取消造成内存泄露
Handler应该申明为静态对象, 并在其内部类中保存一个对外部类的弱引用
解决方案:
使用轻量的数据结构(使用ArrayMap/SparseArray来代替HashMap)
不要使用枚举
在Activity中创建非静态内部类
不要使用枚举
在Activity中创建非静态内部类
内存溢出:指当对象的内存占用已经超出分配内存的空间大小
原因:内存泄露导致 占用内存较多的对象(加载单个超大的图片,造成内存超出限制)。
解决方案:
及时调用recycle 释放不在使用的bitmap
减小Bitmap对象的内存的占用
等比例缩小:inSamplesize
decode format 解码格式 选择ARGB_8888 RGB_565 ARGB_4444
使用更小的图片 ·
减小Bitmap对象的内存的占用
等比例缩小:inSamplesize
decode format 解码格式 选择ARGB_8888 RGB_565 ARGB_4444
使用更小的图片 ·