这篇博文记录的是本人的Android学习过程,从Android基础开始,到实际遇到的问题;html
橘色表示某一范围内的知识点总结;绿色表示分散的小知识点。java
一,Activity 生命周期android
Activity是与用户交互的接口,一个activity对应一个窗口。Android系统中是经过Activity栈的方式来管理Activity的,而Activity自身则是经过生命周期的方法来管理的本身的建立与销毁。git
1. Activity的四种状态github
Active/Running:
web
Activity处于活动状态,此时Activity处于栈顶,是可见状态,可与用户进行交互。算法
Paused:数据库
当Activity失去焦点时,或被一个新的非全屏的Activity,或被一个透明的Activity放置在栈顶时,Activity就转化为Paused状态。但咱们须要明白,此时Activity只是失去了与用户交互的能力,其全部的状态信息及其成员变量都还存在,只有在系统内存紧张的状况下,才有可能被系统回收掉。canvas
Stopped:后端
当一个Activity被另外一个Activity彻底覆盖时(失去焦点而且上层存在不透明的、非Dialog样式的Activity),被覆盖的Activity就会进入Stopped状态,此时它再也不可见,可是跟Paused状态同样保持着其全部状态信息及其成员变量,该Activity的数据会在RAM中暂时保留,一旦系统须要内存,这种处于Stopped状态的Activity占用的RAM空间会优先被清理并从新利用。因此,在Activity处于Stopped状态时,必需要保存该Activity的UI状态,不然一旦RAM空间被从新利用,UI状态和数据就彻底丢失。
Killed:
当Activity被系统回收掉时,Activity就处于Killed状态。不占用RAM空间。
2. Activity的生命周期
典型的生命周期:建立,运行,中止,销毁
onCreate
建立,它是生命周期第一个调用的方法,咱们在建立Activity时通常都须要重写该方法,而后在该方法中作一些初始化的操做。不能在这个阶段写太多耗时的东西。
onStart
运行,此方法被回调时表示Activity正在启动,此时Activity已处于可见状态,只是尚未在前台显示,所以没法与用户进行交互。能够简单理解为Activity已显示而咱们没法看见罢了。
onResume
运行,当此方法回调时,则说明Activity已在前台可见,可与用户交互了(处于前面所说的Active/Running形态)。
onPause
此方法被回调时则表示Activity正在中止(Paused形态),通常状况下onStop方法会紧接着被回调。在onPause方法中咱们能够作一些数据存储或者动画中止或者资源回收的操做,可是不能太耗时,由于这可能会影响到新的Activity的显示——onPause方法执行完成后,新Activity的onResume方法才会被执行。
onStop
通常在onPause方法执行完成直接执行,表示Activity即将中止或者彻底被覆盖(Stopped形态),此时Activity不可见,仅在后台运行。一样地,在onStop方法能够作一些资源释放的操做(不能太耗时)。
onRestart
表示Activity正在从新启动,当Activity由不可见变为可见状态时,该方法被回调。这种状况通常是用户打开了一个新的Activity时,当前的Activity就会被暂停(onPause和onStop被执行了),接着又回到当前Activity页面时,onRestart方法就会被回调。
onDestroy
此时Activity正在被销毁,也是生命周期最后一个执行的方法,通常咱们能够在此方法中作一些回收工做和最终的资源释放。
引用及扩展阅读:
https://blog.csdn.net/qq_35559358/article/details/79715222
https://blog.csdn.net/qingxuan521721/article/details/78737080
二,MVP架构 (Presenter)
只知道MVC,MVP是MVC的改良。主要不清楚presenter的做用。
View:主要负责界面的显示及跟数据无关的逻辑,好比设置控件的点击事件等
Presenter:主要负责View与Model的交互
Model:数据部分
任何须要更新或者操做数据的,都间接经过Presenter对象去操做数据
Presenter层持有View层对象的引用,除此以外不持有其余的UI控件等的引用,Model层会把想要更新View的操做委托Presenter去操做,而Presenter层会把更新View操做交给View层对象去操做。
三,了解 RxJava
a library for composing asynchronous and event-based programs using observable sequences for the Java VM
本质是实现异步操做的库,利用了观察者模式。
观察者模式面向的需求是:A 对象(观察者)对 B 对象(被观察者)的某种变化高度敏感,须要在 B 变化的一瞬间作出反应。程序的观察者模式,采用注册(Register)或者称为订阅(Subscribe)的方式,告诉被观察者:我须要你的某某状态,你要在它变化的时候通知我。相似OnClickListener
。
RxJava 的观察者模式有部分不一样,有四个基本概念:
Observable (可观察者,即被观察者);Observer (观察者);subscribe (订阅);事件
RxJava的事件回调方法有:
onNext() 普通事件
onCompleted() 事件队列完结。RxJava 不只把每一个事件单独处理,还会把它们看作一个队列。RxJava 规定,当不会再有新的 onNext() 发出时,须要触发 onCompleted() 方法做为标志。
onError() 事件队列异常。在事件处理过程当中出异常时,onError() 会被触发,同时队列自动终止,不容许再有事件发出。
线程切换:基本是依靠ObserveOn和SubscribeOn这两个操做符来完成
引用及扩展阅读:
http://gank.io/post/560e15be2dca930e00da1083#toc_1
四,了解Room数据库
google本身的数据库框架Room。
涉及到的概念:
Entity:具体的bean实体(一个对象类称之为一个javabean,不知道为甚),会与数据库表column进行映射
Dao:数据库访问对象,实现具体的增删改查。
RoomDatabase:提供直接访问底层数据库实现,咱们应该从里面拿到具体的Dao,进行数据库操做。
引用及扩展阅读:
https://www.jianshu.com/p/72c8efc3ad87
DAO层操做这个超级全:https://blog.csdn.net/u011897062/article/details/82107709#%E4%BF%A1%E6%81%AF%E6%9F%A5%E8%AF%A2
五,四大组件
Activity:展示为一个可视化的用户界面。这些activity一块儿工做,共同组成了一个应用程序,但每一个activity都是相对独立的。每一个activity都 是Activity(android.app.Activity)的子类。展现activity窗体的可视化内容区域是一些具备层次关系(很是像数据结构中的树)的视图,而视图则是由类View的子类表示的。经过调用Activity.setContentView()方法来设置展示activity的窗体的视图。
Service:Android系统的服务(不是一个线程,是主程序的一部分),与Activity不一样,它是不能与用户交互的,不能本身启动的,需要调用Context.startService()来启动,执行后台,假设咱们退出应用时,Service进程并无结束,它仍然在后台行。好比,service可能在用户处理其余事情的时候播放背景音乐,或者从网络上获取数据,或者执行一些运算,并把运算结构提供给activity展现给用户。每个service都扩展自类Serivce。与activity以及其余组件同样,service相同执行在应用程序进程的主线程中。因此它们不能堵塞其余组件或用户界面,一般需要为这些service派生一个线程执行耗时的任务。
Broadcase receiver:用于异步接收广播Intent。
正常广播 Normal broadcasts(用 Context.sendBroadcast()发送) 是全然异步的。没有定义的顺序。
有序广播 Ordered broadcasts(用 Context.sendOrderedBroadcast()发送)每个receiver执行后可以传播到下一个receiver,也可以全然停止传播--不传播给其它receiver。
专一于接收广播通知信息,并作出相应处理。广播接收器没实用户界面。然而,它们可以启动一个activity来响应它们收到的信息,或者用NotificationManager来通知用户。通知可以用很是多种方式来吸引用户的注意力──闪动背灯、震动、播放声音等等。
Content provider:用于对外共享数据,也就是经过ContentProvider把应用中的数据共享给其它应用訪问,其它应用可以经过ContentProvider对指定应用中的数据进行操做。ContentProvider分为系统的和本身定义的,系统的也就是好比联系人,图片等数据。
以上是四大组件,下面说一下也很重要的intent组件:
intent:一个保存着消息内容的Intent对象。对于activity和服务来讲,它指明了请求的操做名称以及做为操做对象的数据的URI和其余一些信息。比方说,它可以承载对一个activity 的请求,让它为用户显示一张图片,或者让用户编辑一些文本。而对于广播接收器而言,Intent对象指明了声明的行为。比方,它可以对所有感兴趣的对象声 明照相button被按下。对于每种组件来讲,激活的方法是不一样的。此处不赘述,须要阅读,下面有连接~
Application:当android程序启动时系统会建立一个 application对象,用来存储系统的一些信息。一般咱们是不须要指定一个Application的,这时系统会自动帮咱们建立。
引用与扩展阅读:https://www.cnblogs.com/hrhguanli/p/3961599.html
六,Android 布局
时间有限,我是边上手边学的,因此这部分只记录了我以为难一点的地方。
Android 圆角、圆形 ImageView 实现
https://blog.csdn.net/jakezhang1990/article/details/79425879
用glide也是很好的选择
若是图片长宽不定,颇有可能出现上下两条线或者左右两条线的状况,设置android:scaleType="centerCrop" 颇有用,参考以下:
https://www.cnblogs.com/nimorl/p/8081542.html
ConstraintLayout
https://blog.csdn.net/etwge/article/details/80433580
七,View 绘图
1. onMeasure:
做用:
(1)通常状况重写onMeasure()方法做用是为了自定义View尺寸的规则,若是你的自定义View的尺寸是根据父控件行为一致,就不须要重写onMeasure()方法
(2)若是不重写onMeasure方法,那么自定义view的尺寸默认就和父控件同样大小,固然也能够在布局文件里面写死宽高,而重写该方法能够根据本身的需求设置自定义view大小
使用:
onMeasure有两个参数 ( int widthMeasureSpec, int heightMeasureSpec),该参数表示控件可得到的空间以及关于这个空间描述的元数据。widthMeasureSpec和heightMeasureSpec这两个值一般状况下都是由父视图通过计算后传递给子视图的,说明父视图会在必定程度上决定子视图的大小。
specMode一共有三种类型,以下所示:
1. EXACTLY
表示父视图但愿子视图的大小应该是由specSize的值来决定的,系统默认会按照这个规则来设置子视图的大小,简单的说(当设置width或height为match_parent时,模式为EXACTLY,由于子view会占据剩余容器的空间,因此它大小是肯定的)
2. AT_MOST
表示子视图最多只能是specSize中指定的大小。(当设置为wrap_content时,模式为AT_MOST, 表示子view的大小最可能是多少,这样子view会根据这个上限来设置本身的尺寸)
3. UNSPECIFIED
表示开发人员能够将视图按照本身的意愿设置成任意的大小,没有任何限制。这种状况比较少见,不太会用到。
PorterDuffColorFilter
保持原来图片的形状,而切换图片的颜色
ViewOutlineProvider
实现图像矩形圆角效果
class RoundViewOutlineProvider extends ViewOutlineProvider { private float radius = 100f; private int diameter = 200; public RoundViewOutlineProvider(float radius) { this.radius = radius; this.diameter = (int) radius * 2; } @Override public void getOutline(View view, Outline outline) { int left = (view.getWidth() - diameter) / 2; int top = (view.getHeight() - diameter) / 2; int right = view.getWidth() - left; int bottom = view.getHeight() - top; outline.setRoundRect(left, top, right, bottom, radius); } }
八,Android 动画
https://www.jianshu.com/p/609b6d88798d
Android 中的动画能够分为如下几类: 逐帧动画 补间动画 属性动画。
1. 逐帧动画的原理就是让一系列的静态图片依次播放,利用人眼“视觉暂留”的原理,实现动画。逐帧动画一般是采用 XML 资源进行定义的,须要在 <animation-list .../> 标签下使用 <item .../> 子元素标签订义动画的所有帧,并指定各帧的持续时间。
2. 补间动画就是指开发者指定动画的开始、动画的结束的"关键帧",而动画变化的"中间帧"由系统计算,并补齐。补间动画有四种:淡入淡出: alpha,位移:translate, 缩放:scale,旋转: rotate
3. 属性动画能够看做是加强版的补间动画,与补间动画的不一样之处体如今:
属性动画能够看做是加强版的补间动画,与补间动画的不一样之处体如今:补间动画只能定义两个关键帧在透明、旋转、位移和倾斜这四个属性的变换,可是属性动画能够定义任何属性的变化。补间动画只能对 UI 组件执行动画,但属性动画能够对任何对象执行动画。
与补间动画相似的是,属性动画也须要定义几个方面的属性:
主要学习属性动画:
参考引用:https://github.com/OCNYang/Android-Animation-Set/tree/master/property-animation
属性动画实现原理就是修改控件的属性值实现的动画。
类:咱们平时使用属性动画的重点就在于 AnimatorSet、ObjectAnimator、TimeAnimator、ValueAnimator。
属性:Android 属性动画提供了如下属性:
贝塞尔曲线:
一、moveTo:不会进行绘制,只用于移动移动画笔。
二、quadTo :用于绘制圆滑曲线,即贝塞尔曲线。
mPath.quadTo(x1, y1, x2, y2) (x1,y1) 为控制点,(x2,y2)为结束点。一样地,咱们仍是得须要moveTo来协助控制。
mPath.moveTo(100, 500); mPath.quadTo(300, 100, 600, 500); canvas.drawPath(mPath, mPaint);
效果如图:
三、cubicTo:一样是用来实现贝塞尔曲线的。
mPath.cubicTo(x1, y1, x2, y2, x3, y3) (x1,y1) 为控制点,(x2,y2)为控制点,(x3,y3) 为结束点。多了一个控制点而已。
mPath.moveTo(100, 500);
mPath.cubicTo(100, 500, 300, 100, 600, 500);
结果和上图同样。
若是咱们不加 moveTo 呢?则以(0,0)为起点,(100,500)和(300,100)为控制点绘制贝塞尔曲线:
Android Animation运行原理
https://www.jianshu.com/p/fcd9c7e9937e
想要作更酷炫的效果,通常就须要涉及Animation的原理,Android使用一个3*3的矩阵处理平移、缩放、旋转等动画效果,假如咱们想要实现一个平移(a,b)以后旋转(c,d)的动画,那用Matrix的实现代码就是这样的:
Matrix matrix = new Matrix(); matrix.setTranslate(a, b); matrix.postScale(c, d);
Animation的applyTransformation()方法是空实现,具体实现它的是Animation的四个子类,而该方法正是真正的处理动画变化的过程。applyTransformation()方法就是动画具体的实现,系统会以一个比较高的频率来调用这个方法,通常状况下60FPS,是一个很是流畅的画面了,也就是16ms。咱们能够覆写这个方法,快速的制做本身的动画。
https://www.cnblogs.com/kross/p/4087780.html
Android运行时的动画卡顿问题:
个人项目中,页面不只在播放动画,还在播放gif(承载动画的view自己是一个gif),以及还在播放视频,效果是有很明显的卡顿和gif掉帧的。
问题出在内存泄漏,主线程任务过多,以及启用GC频繁。
我查了资料事后,使用了如下硬件加速,结果是没效果。
通过查看GC启用频率,确实启用的很是频繁,想要减小GC,就要尽量少的建立临时变量,因为我使用的是属性动画,建立一个AnimatorSet和多个ObjectAnimation,确实不少,能够尝试这样改改,看有没有效果:
能够按照下面这个博文的思路改代码:
https://blog.csdn.net/rentee/article/details/52251829
====================改完代码的分割线==========================
优化事后,发现内存占用不只没少反多了,emmmmm(没有多不少)
反思了一下,我我的浅薄认为,虽然减小了不少ObjectAnimation对象的建立,可是产生了许多PropertyValuesHolder 对象 以及 Keyframe 对象,并且个人动效比较复杂,常常穿插多个view的动画,最终它们须要在一个set里面,那么仍是不可避免的须要建立ObjectAnimation。 因此改完代码事后,临时变量反而更多了,这些是个人猜想,可是确实在个人实验中,这么写不起优化做用。
这时候看到了另外一个帖子:
https://blog.csdn.net/qiujuer/article/details/42531485
九,反射
https://blog.csdn.net/lwl20140904/article/details/80163880
为何用:
1. private类
2. 须要拿到系统级的类
获取Class对象的三种方式
1 Object ——> getClass();
2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
3 经过Class类的静态方法:forName(String className)(经常使用)
经常使用第三种方法
譬如说作SDK的时候,想要引用某个包的时候,能够用这种方式,找获得就用,找不到就不用。
GSON内部也是用反射找到输出类型的类,并返回对象。
单例实现的效果是用来作内存级别的操做,实现缓存
缓存
内存缓存 红位数 loser cache
内存缓存的意义是更快的用数据,能够用各类算法。
十,WebView
WebView是android中一个很是重要的控件,它的做用是用来展现一个web页面。它使用的内核是webkit
引擎,4.4版本以后,直接使用Chrome做为内置网页浏览器。
https://www.jianshu.com/p/3e0136c9e748
原子操做
"原子操做(atomic operation)是不须要synchronized"
原子操做是指不会被线程调度机制打断的操做;这种操做一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另外一个线程)。
若是把一个事务可看做是一个程序,它要么完整的被执行,要么彻底不执行(回滚)。这种特性就叫原子性。
经常使用的XML解析方法
sax:基于事件驱动,逐条解析,适用于只处理xml数据,不易编码,并且很难同时访问同一个文档中的多处不一样数据
dom:Dom解析是将xml文件所有载入到内存,组装成一颗dom树,而后经过节点以及节点之间的关系来解析xml文件,与平台无关,java提供的一种基础的解析XML文件的API,理解较简单,可是因为整个文档都须要载入内存,不适用于文档较大时。
JDOM:简化与XML的交互而且比使用DOM实现更快,仅使用具体类而不使用接口所以简化了API,而且易于使用
DOM4j:JDOM的一种智能分支,功能较强大,建议熟练使用
内部类和静态内部类
内部类会持有外部类的对象,打印构造函数是能够看到的,JVM在编译阶段会加进去。
1. 对象建立的方式不一样
静态内部类建立对象的时候,独立于外部类及其对象,就好像它是一个独立的类,能够和外部类同样使用。
内部类建立对象的时候,不能独立于外部类,必需要先建立外部类的对象,而后再用这个对象来new出内部类的对象。
2. 内部类不能够有很是量的静态成员
缘由很简单,静态成员能够不依赖于对象使用,若是内部类有静态成员的话,就至关于外部类对象直接调用内部类的静态成员,一个是对象,一个是类,不三不四的。
因此,要给内部类的定义静态成员,必需要使用静态内部类。
非静态内部类是在外部类对象产生的时候才会初始化,因此在没有产生对象时,内部类自己尚未被初始化,这个时候声明一个静态成员,静态成员必须在类加载的时候被加载,因此不能被声明。
匿名内部类
https://blog.csdn.net/hellocsz/article/details/81974251
Listener就是用了匿名内部类。
若是想要在以后remove匿名内部类里面的东西,就不要这么写了,拿不到句柄没法remove。
接口和抽象方法
https://blog.csdn.net/frankfan123/article/details/79628034
设计模式——模板方法模式
https://www.cnblogs.com/chenpi/p/5217430.html
baseActivity 就是用到了这个。
setContentView 做用与用法
做用:给当前activity设置一个layout布局
安卓里的用户界面放在res.layout下,为xml文件,系统自动生成R类,R.layout自动获取res.layout文件夹中的xml文件,再用该语句调用。以后就能够看到页面啦。
setContentView(R.layout.main);
findViewById 做用与用法
做用:获取layout中的某个组件,以便于操做该组件,常见于view,button。
findViewById(R.id.xml文件中对应的idName)
Map<Integer, String> 和 set<Integer>
set集合:元素不容许重复,无序,容许null但最多有一个。
HashMap:无序(Tree有序),遍历Map过程当中,不能用map.put和map.remove,会引起 并发修改异常,能够经过迭代器的remove(),从迭代器指向的 collection 中移除当前迭代元素来达到删除访问中的元素的目的。
Map不能用=赋值,用map.put(key,newVal)
// map初始化,以及set初始化和赋值 Map<Integer, String> map = new HashMap<>();
map.put(1, "hihihihihihi"); Set<Integer> set = map.keySet(); //获取map所有key
Java 遍历Map时 删除元素:https://www.cnblogs.com/wxmdevelop/p/5549548.html
final 的用法
final若是修饰类,该类不能被继承;
final若是修饰变量,该变量不能被修改,不能再从新赋值,即变为常量;
final若是修饰方法,该方法不能被重写;
只有被final修饰的局部变量能够用在内联方法里。
使用final的目的大概有如下两条:
一、Java中内部类调用外部类局部变量时要final。
二、当咱们写的代码行已经不少的时候,本身可能就忘了以前的意图,把button改了,结果就是:没有按照咱们的意愿运行,而后报错。而final修饰后,是不容许修改的,就避免了这样的错误。
引用:
https://www.jianshu.com/p/fd7ce9e3eecb
GSON
GSON是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。能够将一个Json字符转成一个Java对象,或者将一个Java转化为Json字符串。
Handler的做用与用法
Handler是Android SDK来处理异步消息的核心类。子线程与主线程经过Handler来进行通讯。子线程能够经过Handler来通知主线程进行UI更新。
个推,以及什么透传消息
文档里面有一句写了:消息推送以个推的透传消息实现。不知道这个透传是什么
透传,即透明传输(pass-through),指的是在通信中无论传输的业务内容如何,只负责将传输的内容由源地址传输到目的地址,而不对业务数据内容作任何改变。
百科的意思大概就是东西是什么就传什么,那为何要这样作呢?
透传消息,就是消息体格式及内容,对于传递的通道来讲是不去过问的,通道只负责消息的传递,对消息不作任何处理,当客户端接收到透传消息后,由客户端本身来决定如何处理消息。正是由于透传消息能够自定义消息体,也能够自定义消息的展现方式及后续动做处理,因此弥补了通知栏消息的一些不足之处(通知栏消息是直接展现出来,相关的动做客户端没法捕获到)。
透传消息是必须打开应用才能收到,通知是杀死应用也能收到。
看完仍是有点不懂,以及如何实现呢
引用和扩展阅读:https://blog.csdn.net/u011136197/article/details/78921988
pollFirst
java.util.LinkedList.pollFirst() 方法检索并移除此列表的第一个元素,或者若是此列表为空,则返回null。
LinkedList
LinkedList 是一个继承于AbstractSequentialList的双向链表。它也能够被看成堆栈、队列或双端队列进行操做。
LinkedList<X> x= new LinkedList<>();
LinkedList.clear() 用于从连接列表中删除全部元素。使用clear()方法只会清除列表中的全部元素,而不会删除列表。换句话说,咱们能够说clear()方法仅用于清空现有的LinkedList。
扩展阅读:https://www.cnblogs.com/skywang12345/p/3308807.html
adb pull does not exist
必定要记得先adb remount一下,否则没有读写权限,就找不到设备报does not exist的错误😭
实现list分红20个为一组
int userNum = list().size(); // for ( int i = 0; i<=userNum/20; i++ ){ List<String> whiteList = new ArrayList<>(); for (int j = 0;j<20;j++){ whiteList.add(list().get(i*20+j)); if ( list().size() == i*20+j+1 ) break; } //功能代码区 }
java.lang.ExceptionInInitializerError
抓下来,提示java.lang.ExceptionInInitializerError,因而去找解决办法。
extends
在Java中,经过关键字extends继承一个已有的类,被继承的类称为父类(超类,基类),新的类称为子类(派生类)。
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo
java.lang.ClassNotFoundException: Didn't find class "***" on path: DexPathList[[zip file
出现这个bug的缘由有不少,百度一下你能够看到;我试过了网上能找到的全部方法都不行……找了前辈帮忙才解决,说一说我这里报错的缘由:类名的命名规范采用大驼峰命名法,必定要严格遵照!我一开始所有小写,改为开头大写就可了。
关于命名规范扩展阅读:https://blog.csdn.net/wenzhi20102321/article/details/61650405
给Thread传递参数
https://www.cnblogs.com/larrylawrence/p/3517897.html
这个文给了我很好的想法,用另一个有参函数setTar()传递参数。或者能够用回调
延迟执行
若是能够用handler delay写,尽可能不要起线程写Thread.sleep。
a method on a null object reference
某方法在一个空指针引用里,有两种状况:1. 实例对象没有实例化 2. 调用的方法返回了NULL给实例,而后实例又去作操做。我检查后发现确实是实例对象没有实例化。
资源复用
新建对象会占用cpu,对象的保留会占用内存,销毁也会占用资源,特别是画图这类的动做。因此尽可能减小动做发生,一个解决办法是创建回收机制/等待区,把不用的对象放在等待区,用的时候再引用它们。下面举个栗子:
Android自定义属性时TypedArray的使用方法
https://blog.csdn.net/qq_36523667/article/details/79289821
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
不能在子线程中更新ui
RxJava轮询器:interval
https://www.jianshu.com/p/03958daf4b82
getInstance()
https://www.cnblogs.com/roadone/p/7977544.html 使用getInstance()方法的缘由及做用
总的来讲:这是单例模式,通常用于比较大,复杂的对象,只初始化一次,应该还有一个private的构造函数,使得不能用new来实例化对象,只能调用getInstance方法来获得对象,而getInstance保证了每次调用都返回相同的对象。
getInstance每每是static的。
Android实现两个循环动画之间互相中断执行,clearAnimation()会致使的bug
中断动画用的clearAnimation(),若是此时动画已经开始执行了,就不能阻止它完成,而且会执行onAnimationEnd;若是在这个阶段,再一次执行这个动画,而且做用在同一个view上,会致使以前clear掉的动画又出现,而且此时两个动画在一个view上,互相牵制,这就是这个错误的表现,跟踪会发现是这个view上有两个动画。
这种状况会出现咱们想要在两个动画之间相互切换,A动画在循环的过程当中被中断,执行B动画,而A动画并不会马上中断,仍是会去执行onAnimationEnd,而在这个阶段B动画被中断,执行A动画,以前那个动画也会被执行。
Warning: Static member accessed via instance reference
Warning:
Static member accessed via instance reference 经过引用实例来访问静态成员
Shows references to static methods and fields via class instance rather than a class itself. 经过类的实例来显示静态方法和变量的引用,而不是经过类自己
现有一个类Test,有静态方法methods和静态属性fields。
对于静态变量或方法,推荐使用的方式是Test.fields,而不是new Test().fields。
固然,使用this.fields也是不行的!由于this也指向一个实例对象。
若是出现以上告警,那必定是对于java不推荐的方式使用了静态元素。
504错误
504错误是(网关超时) (Gateway timeout) 服务器做为网关或代理,可是没有及时从上游服务器收到请求。
这个问题彻底是由后端电脑之间 IP 通信缓慢而产生。
Shallow Size、Retained Size、Heap Size 和 Allocated
https://blog.csdn.net/strange_monkey/article/details/81746232
Shallow size就是对象自己占用内存的大小,不包含其引用的对象。
Retained Size 就是该对象被 Gc 以后所能回收内存的总和。
Retained Size = 对象自己的Shallow Size + 对象能直接或间接访问到的对象的Shallow Size
Heap Size:堆的大小,当资源增长,当前堆的空间不够时,系统会增长堆的大小,若超过上限(如64M,阈值视平台而定)则会被杀掉 。
Allocated:堆中已分配的大小,即 App 应用实际占用的内存大小,资源回收后,此项数据会变小。
建议:若单一操做反复进行,堆大小一直增长,则有内存泄露的隐患,可采用MAT进一步查看。
session
public key 发送给服务端,服务端再生成一个···
请求框架:
retrofit+okhttp
下载:downloadManager 支持断点续传……
getSimpleName名字会比getName更短。
Java反射机制:反射到名字变化多的地方,被混淆的东西,就会报错,要注意。
模块化的时候会用到;调用SDK的时候;调用第三方库;调用系统 …… 的 private成员
注解
混淆
model.bin
部署模型https://www.jianshu.com/p/43da2553a2fb
播放器部分:
mediaplayer:
mediaplayer采用recycleview,有复用机制。可是传入新数据的时候,就会new新的,可是以前的view
还能够用exoplayer
final 和effectively final
针对于jdk1.8,对于一个变量,若是没有给它加final修饰,并且没有对它的二次赋值,那么这个变量就是effectively final(有效的不会变的),若是加了final那确定是不会变了哈。就是这个意思。
在使用内部类的时候,一个外部变量不能直接被用,但若是它是final或者effectively final就能够被内部类使用了。