Android - 寻找Handler,main()方法

快捷键:

提取方法:Ctrl+Alt+M    提取全局变量:Ctrl+Alt+F  搜索类:ctrl+N

断点调试时,遇到这个 端口号被占用

Connected to the target VM, address: 'localhost:8610', transport: 'socket'

 

短视频

原理:

  • 编码与解码:视频压缩成文件还原成帧图像,h264。
  • 封装格式
  • 硬解码(gpu)、软解码(cpu)、多线程解码
  • 关键帧:视频压缩当中比较重要的图像帧数据

Raw文件夹:一般大文件都存放在Raw和assets文件夹

 Bundle的概念:Bundle类型的数据与Map类型的数据相似,都是以key-value的形式存储数据的

界面跳转:intent-fiter和Intent

Intent中文意思指“意图”,通常Intent的隐式启动和intent-filter连用,显示启动不需要intent_filter。

IOC原理:控制反转 https://www.jianshu.com/p/f96391af0357

观察者设计模式:观察者与被观察者 (以VideoView demo举例,观察者是界面,被观察者就是播放器)

Handler原理图:

 

setContentView原理:把自定义Layout加入id为content的ViewGroup里

findViewById:根据xml id值来映射成view对象

VideoView:对MediaPlayer的一层封装,只支持3gp和mp4格式的播放。

清单文件:权限 、四大组件、PMS(Package Manager Service)安全检查

VideoView全屏:videoView会根据视频大小来改变自身的大小,所以要自定义view。

style自定义属性的复用

Android中View和ViewGroup是组合设计模式之一(共23种)

自定义view的几种方式:

1.继承View完全自定义

对于继承View类的自定义控件来说,核心的步骤分别为尺寸测量与绘制,对应的函数为onMeasure、onDraw,这是因为View的子空间是视图树的叶子节点,不需要布局(针对为什么布局开发时有actionBar,但运行后app播放器仍然充满屏幕)

小技巧:查找类【Ctrl+N】

TextView类中

2.继承现有控件实现特定效果

3.继承ViewGroup实现布局类

这种方式主要用于自定义子视图的排列方式时,比如下拉刷新,上拉加载等。

ViewGroup具有容器作用:因为实现了两个接口ViewParent和ViewManager,其中后者定义了addView及removeView等对子视图操作的方法,重点实现onLayout方法,这个方法主要是用于子视图的排放。

public class FrameLayout extends ViewGroup 该类下有onLayout方法


 

EXACTLY模式

该类为精确模式。何时使用:

当我们将layout_width or layout_height 设置为具体数值时,如100dp或是match_parent,这是系统就是调用精确模式。

AT_MOST

最大值模式,当我们将layout_width or layout_height设置为wrap content时,系统调用的就是这个模式

此时的控件大小是随着子控件或者内容的变化而变化,只有不超出父控件允许的最大范围即可

UNSPECIFIED

只有在自定义控件时用到,没有具体的测量,view自己想要多大有多大

自定义计时器:用Handler的消息机制做数据的减法操作

TextView:

自定义Shape:不自定义可以使用图片,自定义shape用xml代码实现

颜色色值:#ffffffff由#加八位数字或字母组成,前两个ff为透明度(十六进制),后面六位ffffff为颜色代码,采用RGB配色(十六进制)

透明度参照表:

00%=FF(不透明) 5%=F2 10%=E5 15%=D8 20%=CC
25%=BF 30%=B2 35%=A5 40%=99 45%=8c
50%=7F 55%=72 60%=66 65%=59 70%=4c
75%=3F 80%=33 85%=21 90%=19

95%=0c

100%=00 (全透明)

解决硬编码:把代码里面的中文字提出到String.xml文件,一些常量可单独提出到常量类里面,注意未来界面整洁,维护,规范

dp px sp 之间的概念

px:像素单位        dp:安卓距离单位     sp:安卓字体大小单位

密度 ldpi mdpi hdpi xhdpi xxhdpi
密度值 120 160 240 320 480
代表分辨率 240*320 320*480 480*800 720*1280 1080*1920

当屏幕为mdpi时,1dp=1px,换算单位为dp=(dpi/160)px

1dp永远都等于1sp

Bundle的概念:Bundle 类型的数据与Map类型的数据相似,都是以key-value的形式存储数据的

界面跳转:intent-filter和Intent

Handler原理:

线程之间的通信(子线程处理一些结果,通过handler发送到主线程,主线程通过一些方法“handleMessage()”来获得数据)

死循环不会卡死:

这里涉及到Linux pipe/epoll机制,简单来说就是在主线程的messageQueue没消息时,便阻塞在loop的queue.next()中的nativePollOnce()方法里,此时主线程会释放CPU资源进入休眠状态,直到下个消息到达或者有事务发生,通过往pipe管道写端写入数据来唤醒主线程工作。

断点调试

注意1!!!

//countDownTime一开始是0,需要在这里设置传入time
        this.countDownTime = time;

 注意2!!!当countDownTime == 0的时候,先把它取消掉,在还在进行onCreate()时,是自动取消Handler

如果说Activity还没有走完,Handler是否还会继续存在呢?添加cancel()

注意3!!!所以才需要手动调用一次

onCreate(),onDestory()都是系统调用的

SplashActivity添加

//界面销毁时,回调
    @Override
    protected void onDestroy() {
        super.onDestroy();
        timer.cancel();
    }

Handler原理寻找

  

 

loop类loop()构造器

往下滑找到Looper()

创建Handler的时候,会去ThreadLocal里面去取这个Looper,这个Looper的构造方法创建MessageQueue()

为什么用ThreadLocal去取,而不是新建一个呢?

这就涉及系统源码,关于主线程Looper和MessageQueue在app刚启动的时候就已经创建出来了,它们是在ActivityThread类

快速双击shift,搜索ActivityThread.java,它是一个app程序的入口,搜索main(String[] args),一般操作系统都有这么一个main()

这里面有一个prepareMainLooper(),就相当于创建了一个Looper,还需要调用一个Looper.loop()


 

然后拿到个MessageQueue不断去遍历

这是个Message类,点进去,它里面有what,arg1,arg2这些标识

点击CustomCountDownTimer中post(),调用sendMessageDelayed()

它把Runnable这个对象封成了一个Message,这样就解释通了

根据handler原理图,我们发送一个Runable,实际上我们也封装了一个Message到消息队列里面,在app程序启动的时候,不断去循环MessageQueue

它是把Runnable这个对象封装在MesageQueue的callback这个成员变量里面。

它定义了一些code,发送不同消息的一些类型,然后去回调处理这个handleMessage

Activity的生命周期:就是通过ActivityThread发送一些消息,处理不同消息类型,去调用Activity的生命周期

上传至github

首先建立仓库

commit

push

公司项目多人开发需要建立分支,可参考https://www.cnblogs.com/myqianlan/p/4195994.html

开发的一个分支Feature完成后,再develop合并,经过测试完后,最后master(以及还有从master拉出来hotfix进bug修改发版,拉出Release分支用于打包)

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章