基础常识

四大组件

1.活动Activity
2.服务 service
3.内容提供者 content provider
4.广播 Broadcast

service 相关

  • Android四大组件之一, 作用: 提供需在后台长期运行的服务, 场景: 复杂计算、音乐播放、下载等
  • 特点:无用户界面、在后台运行、生命周期长
  • 相关链接: https://www.jianshu.com/p/d963c55c3ab9

      1. 长生命周期 无界面
    • 2.应用场景: 音乐播放器, 检测sd 的变化,在后台记录地理位置信息
      1. onCreate –> onStart(可多次调用)/–> onStop() –> onDestroy
    • onCreate –>onBind() –>onUnBind()–>onDestory();
      1. 启动方式: (1).startService()组件启动service 之后,没有反馈结果
    • (2).bindService()如果宿主自己的生命周期结束了,bindService模式就要先把服务给销毁掉
      https://www.jianshu.com/p/ee224f18a4bd

brocastReceiver

  1. 阐述: 而BroadcastReceiver 是对发送出来的Broadcast进行过滤接受并响应的一类组件。可以使用BroadcastReceiver 来让应用对一个外部的事件做出响应.例如(打电话, 程序卸载完成)
  2. NotificationManager ,没有UI 来告知用户事情发生了.
  3. 注册方式: 清单文件静态注册(无论程序处于活动状态,都会进行监听), 代码动态注册(生命周期随aty ,比较推荐)

Content Provide

给不同应用提供内容访问,多进程通信方式

handler机制

  • 4.0开始,主线程请求网络异常,利用handler处理,(AsyncTask,Volly,
  • Bus对其进行巧妙封装)
  • 主要包括Message,MessageQueue,Looper以及Handler。
  • Looper 持有MessageQueue
  • Message定义了消息必要的描述和属性数据
  • MessageQueue 用来存放消息的消息队列
  • Handler作为消息处理者,一是处理Message,二是将某个Message压入MessageQueue中
  • handler 开始结束 mHandler.removeCallbacks(mRunnable)或者handler.removeMessages(what); 在new MyHandler()的时候开始.
  • 一个线程对应一个looper().MessageQueue对象
  • ThreadLocal:MessageQueue对象,和Looper对象在每个线程中都只会有一个对象,怎么能保证它只有一个对象,就通过ThreadLocal来保存。Thread Local是一个线程内部的数据存储类,通过它可以在指定线程中存储数据,数据存储以后,只有在指定线程中可以获取到存储到数据,对于其他线程来说则无法获取到数据。
通过Looper的prepare方法创建MessageQueue
通过loop方法找到和当前线程匹配的Looper对象me
从me中取出消息队列对象mQueue
在一个死循环中,从mQueue中取出Message对象
调用每个Message对象的msg.target.dispatchMesssge方法(去除)
也就是Handler的dispatchMessage 方法
在dispatchMessage 根据Message对象的特点执行特定的方法。
1. Android 为什么设计只能通过handler机制更新UI呢
    根本是为为了解决多线程并发问题,子线程不加锁会导致界面更新错乱. 线程加锁导致性能低下(不提倡)
handler负责发送消息,Looper负责接收handler发送的消息,并吧消息传给Handler自己
Handler与MessageQuee 关联:通过Handler的构造方法 赋值messageQuee
主线程给子线程发送消息:
handlerThread: 解决多线程并发问题:

mvc与mvp

mvc

  • m Model: 对应的则是一些DataSource以及DataBean的相关对象,这里的DataSource指的是数据的来源. (model不只是很简单的一个数据结构定义,更多的它应该包含大量的数据处理和运算的逻辑)
  • v View: 对应的则是Android中的layout文件夹中的xml文件
  • c Controller: 对应的则是Activity/Fragment

mvp

  • m
  • v
  • p Presenter:主持者层,它相当于是Controller中的业务逻辑部分,它主要是负责view和model层之间的通信

MVP特点:

* view和model之间的通信必须是通过presenter的传递,视图和数据分离,
* 两者之间定义通用接口IContract
* 

参考链接:
http://blog.csdn.net/yang542397/article/details/78074629

apk打包过程

  • 其实是一个zip压缩包, 可以进行解压
  • classes.dex 是apk应用的核心,是源码生成.class文件,利用dex工具转换成虚拟机识别的二进制代码.

把java 文件 –>dex dex+资源文件+清单文件–>apk

屏幕适配

  • dp 不能解决所有的适配, 最理想的是用百分比
    (1. 用代码动态计算太麻烦,
    1. linearLayout 的weight来实现,但是不是适用于所有的场合)
  • 解决: 1.多使用match_parent,2.多用weight,3.自定义view解决.
  • 不同文件夹drawable-hdpi 里面存放的图片是==屏幕密度==(屏幕密度和分辨率没有关系)

自定义控件:

参考慕课网视频:
* 1.继承系统控件, 2.组合系统控件,3.自定义绘制控件.
* 日历控件自定义

权限

对用户的隐私保护力度越来越大.
Android 6.0 动态权限组
7.0 私有目录限制访问

事件分发机制

  • 触摸任何一个view,都会调用dispatchTouchEvent. 一直向上查找到view,
  • onTouch肯定是要优先于onClick执行, onTouch返回true,onClick就不会再执行
  • onTouch和onTouchEvent有什么区别

    1.两个方法都在view的dispatchTouchEvent中调用,onTouch优先于onTouchEvent,若在onTouch 中返回true,消费掉事件,onTouchEvent 不会执行.
    2.onTouch 执行条件, 控件是可以enable,mOnTouchListener 不能为空.
    

    * ViewGroup事件分发

    viewGroup包括子view和子viewGroup
    
    1.android 事件分发是先到viewagroup 然后到view,
    2. ViewGroup中可以通过onInterceptTouchEvent,返回true代表不允许事件继续向子View传递,返回false代表不对事件进行拦截,默认返回false
    3. 子View中如果将传递的事件消费掉,ViewGroup中将无法接收到任何事件
    

view绘制

  • 每个Activity都有一个Window(具体来说是PhoneWindow)相关联,用户界面则由Window所承载
  • setContentView()的整体执行流程 :实际上调用到了PhoneWindow的setContentView()方法,最终调用最终调用的是inflate(XmlPullParser, ViewGroup, boolean)方法来填充布局.
  • View的绘制是由ViewRoot来负责:::
  • 绘制流程:
    绘制背景; <br>
    通过onDraw()绘制自身内容; <br>
    通过dispatchDraw()绘制子View; <br>
    绘制滚动条</li>
    


https://www.jianshu.com/p/060b5f68da79 (详细) http://www.codekk.com/blogs/detail/54cfab086c4761e5001b253f

动画

  • 3.0之前传统动画,之后是属性动画(property Animation)
  • 传统动画: 补间动画(Tween) 帧动画(Frame Animation).布局动画(Layout Animation)
  • *

bitmap优化:

  • 大图片 或者多张,可能引起卡顿,

bundle机制

它和Map类型有异曲同工之妙,同时实现了Parcelable接口,那么显然,它是支持进程间通讯的。所以,Bundle可以看做是一个特殊的Map类型,它支持进程间通讯,保存了特定的数据.

hashMap与hashTable

  • 都使用哈希表来存储键值对。在数据结构上是基本相同的
  • hashMap: 后来在hashTable的基础上演变来的, 线程不安全,效率高 允许null值和键,HashMap默认的初始化大小为16,之后每次扩充为原来的2倍,HashMap是支持null键和null值的
  • HashTable: 默认的初始大小为11,之后每次扩充为原来的2n+1,ConcurrentHashMap代替

activity 四种启动方式

  1. standard singleTop singleTask singleInstance

  2. activity 被复用之后中间的aty 会被清除.

onNewIntent()

  1. 复用Activity时的生命周期回调,onNewIntent(),
  2. Activity第一启动的时候执行onCreate()—->onStart()—->onResume()等后续生命周期函数,也就时说第一次启动Activity并不会执行到onNewIntent(). 而后面如果再有想启动Activity的时候,那就是执行onNewIntent()—- >onResart()——>onStart()—–>onResume().
  3. 如果android系统由于内存不足把已存在Activity释放掉了,那么再次调用的时候会重新启动Activity即执行onCreate()—->onStart()—->onResume().

布局优化

优化方向:布局性能、布局层级、布局复用性 和 测量 & 绘制时间用来提高界面的显示速度.
(https://juejin.im/entry/5af8e7b26fb9a07acc11d18d)

  1. 选择耗费性能少的布局,详见(## LinearLayout 与RelativeLayout )
  2. 减少布局的层级嵌套(使用布局标签 & 合适选择布局类型,提高布局的复用性,使用 布局标签,布局属性 wrap_content 会增加布局测量时计算成本,应尽可能少用)

代码优化

1.多使用封装好的api,

LinearLayout 与RelativeLayout

不得不使用 ViewGroup 多重嵌套时,不要使用 LinearLayout 嵌套,RelativeLayout,可以有效降低嵌套数
1. LinearLayout ,FrameLayout 耗费性能低,
2. RelativeLayout 耗费性能高, 布局复杂

String,StringBuilder,StringBuffer三者的区别

  1. 速度: StringBuilder >StringBuffer >String,
  2. 安全:StringBuilder(适用于单线程)是线程不安全的,而StringBuffer是线程安全的(适用多线程下)
  3. string 不可变, 其内部成员变量全部使用final来修饰,保证成员变量的引用值只能通过构造函数来修改;

Tcp与UDP

  1. TCP :
  2. UDP:
  3. tcp协议和udp协议的差别
    TCP UDP
    是否连接 面向连接 面向非连接
    传输可靠性 可靠 不可靠
    应用场合 传输大量数据 少量数据
    速度 慢 快
    (参考链接)https://blog.csdn.net/air_hjj/article/details/70791852

rxJava 使用

  1. 合并多个网络请求:

    Flowable.zip() 合并后同时发送, 一个出错全部都出错走onError()
    Flowable.merge() merge是不按顺序发送事件
    Flowable.concat() 顺序发送
    map或flatMap操作符 请求之间存在相互依赖关系.
    (https://blog.csdn.net/f1313131/article/details/78475747)

  2. 被压Backpressure

    背压是指在异步场景中,被观察者发送事件速度远快于观察者的处理速度的情况下,一种告诉上游的被观察者降低发送速度的策略

    Flowable是为了解决背压(backpressure)问题

    https://www.jianshu.com/p/2c4799fa91a4

  3. 操作符

    类型          描述
    Observable<T>   能够发射0或n个数据,并以成功或错误事件终止。
    Flowable<T>     能够发射0或n个数据,并以成功或错误事件终止。 支持Backpressure,可以控制数据源发射的速度。
    Single<T>   只发射单个数据或错误事件。
    Completable     它从来不发射数据,只处理 onComplete 和 onError 事件。可以看成是Rx的Runnable。
    Maybe<T>    能够发射0或者1个数据,要么成功,要么失败。有点类似于Optional
    
    • 使用场景:
      遍历
      提取某条数据
      处理耗时操作

https://www.cnblogs.com/ztzf-xd/p/7710724.html

EventBus 使用

  • 应用程序的各组件、组件与后台线程间进行通信,比如在子线程中进行请求数据,当数据请求完毕后通过Handler或者是广播通知UI,而两个Fragment之家可以通过Listener进行通信等等。当我们的项目越来越复杂,使用Intent、Handler、Broadcast进行模块间通信、模块与后台线程进行通信时,代码量大,而且高度耦合.

    1. 粘性事件:@Subscribe(priority = 100,sticky = true)priority越大优先级越高

    EventBus也可以终止对事件继续传递的功能
    @Subscribe(priority = 100) public void onToastEvent(ToastEvent event){
    Toast.makeText(MainActivity.this,event.getContent(),Toast.LENGTH_SHORT).show();

    EventBus.getDefault().cancelEventDelivery(event); 
    

    }

    1. 普通事件:
    2. 四种线程模式(thread)类型
      • POSTING (默认) 表示事件处理函数的线程跟发布事件的线程在同一个线程。
      • MAIN 表示事件处理函数的线程在主线程(UI)线程,因此在这里不能进行耗时操作。
      • BACKGROUND 表示事件处理函数的线程在后台线程,因此不能进行UI操作。如果发布事件的线程是主线程(UI线程),那么事件处理函数将会开启一个后台线程,如果果发布事件的线程是在后台线程,那么事件处理函数就使用该线程。
      • ASYNC 表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行UI操作。

https://www.jianshu.com/p/251a1e1b793a

Integer 和 int 之间的区别

  1. Integer是int提供的封装类,而int是Java的基本数据类型; Integer默认值是null,而int默认值是0; 声明为Integer的变量需要实例化,而声明为int的变量不需要实例化; Integer是对象,用一个引用指向这个对象,而int是基本类型,直接存储数值
  2. 两个new 出来的Integer总是不一样的。当使用==时,发现其内存地址不同,所以进行==返回false

listView 与RecyclerView

  1. 为什么listview 没有被代替:ListView采用的是RecyclerBin的回收机制在一些轻量级的List显示时效率更高.
  2. ListView优势:(1).添加头视图和尾视图,(2).android:divider”设置自定义分割线,(3).点击事件.(简单功能可用)
  3. 与RecyclerView优势:(1).默认已经进行复用,回收机制更加完善(2).默认支持局部刷新(3).容易实现item添加删除动画效果(4).容易实现拖拽侧滑
  4. RecyclerView是一个插件式的实现,对各个功能进行解耦,从而扩展性比较好.
    https://blog.csdn.net/cuiyufeng2/article/details/54409456

AsyncTask 内部实现原理

性能优化:

  1. 布局优化:
  2. 内存优化:
    每个app分配内存限制,随设备不同. 图片特别吃内存.
    GC 回收线程暂停
    切换应用后台app 清理机制: LRU Cache(最近最少使用) onTrimMemory(int level)
    数据结构优化: 频繁字符串拼接StringBuilder
    ArrayMap,SpareArray 代替HashMap
    内存抖动(大规模变量声明不当)
    每个class 最小占用0.5kb
    HashMap一个enty 额外占用32b**

对象复用: 复用系统自带资源 \
ListView GridView的ConvertView复用\
避免onDraw()(频繁执行)方法里面执行对象创建

内存泄露:会频繁导致GC.
注意Activity 泄露, 用Application Context代替Activity context. Cousor 及时关闭

Android层面:

  1. Android 手机屏幕每秒刷新60帧,大概需要16ms.每隔16ms触发对UI进行渲染,超过时间界面卡顿,通过工具检测,布局是否复杂,观察Gpu,cpu,找到性能瓶颈

  2. 过度绘制

  3. gc 内存抖动,Android Studio中的Memory Monitor查看程序的内存使用
  4. 请求捆绑,压缩
  5. 对于不透明的View,显示它只需要渲染一次即可,可是如果这个View设置了alpha值,会至少需要渲染两次
  6. onDraw()方法是执行在UI线程的,在UI线程尽量避免做任何可能影响到性能的操作
  7. View.invalidate()会触发View的重绘
  8. 尽量减少PNG图片的大小是Android里面很重要的一条规范。相比起JPEG,PNG能够提供更加清晰无损的图片,但是PNG格式的图片会更大,占用更多的磁盘空间。到底是使用PNG还是JPEG,需要设计师仔细衡量,对于那些使用JPEG就可以达到视觉效果的,可以考虑采用JPEG即可
  9. ArrayMap代替hashMap(占内存自动装箱)
  10. 发起网络请求与接收返回数据都是比较耗电的,应该减少网络请求的频率,这是为了减少电量的消耗
  11. 减少移动网络被激活的时间与次数,压缩传输数据
  12. 高程序的启动速度
  13. 移除那些在程序中使用不到的代码与资源,帮助减少APP的安装包大小

http://www.jackywang.tech/AndroidInterview-Q-A/chinese/subject/性能优化.html (较全面)

OOM

  1. 主要是图片问题,
  2. 软引用 :在生命周期内,内存不足会被回收, 强引用 不会
  3. oom优化:
          临时bitmap 尽快处理或者回收(置为空或者回收) <br>
          避免bitmap 浪费/ <br>
          加载bitmap:缩放比例,解码格式,局部加载  </li>
    

Gilde 缓存

  1. 前言:
    • 一般缓存模块设计都会有磁盘缓存和内存缓存这两级缓存。移动设备中对内存的使用管理要求很高,而图片资源往往是比较占内存的。
    • Android 中图片的显示实体是 Bitmap 对象,每次图片显示时会将图片资源构建成一个 Bitmap 对象,创建 Bitmap 和销毁 Bitmap 是比较消耗系统资源的,所以能让 Bitmap 可复用可有效降低 Bitmap的创建和销毁和频繁的内存申请和释放操作,从而减少卡顿提高应用性能。
  2. glide:
    • 中为了复用 Bitmap 构建了一个 bitmappool,图片的 Bitmap 的申请和释放都需要通过它来处理。需要加载新的图片时,先从 BitmapPool 中查找有没有相应大小或者稍大一点的 Bitmap,有则直接使用,没有再创建新的 Bitmap。一个长列表中的图片往往是大小相同的,所以这个复用率还是相当可观的。
    • activeResource 缓存,存放的是正在使用的图片资源对象,数据结构为HashMap

Enum 枚举使用:

Android中是不推荐使用的,
Enum 需要占用较大的内存,如果对内存敏感,请尽量少使用 Enum,换用做静态常量。
枚举一般需要比静态常量超过两倍多的内存。

附录

android基础很全参考:
https://juejin.im/post/598f00da51882548630c0eab

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值