v1 v2 v3签名
https://juejin.cn/post/6906882748909092871
https://zhuanlan.zhihu.com/p/108034286
https://tech.meituan.com/2017/01/13/android-apk-v2-signature-scheme.html
打包
批量方案:解压签名的apk,删除meta-inf,将渠道号写入assets目录下的channel文件中,再重新生成jar并签名
https://www.jianshu.com/p/5baea0e1cd1e?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
jeykins
https://www.jianshu.com/p/38b2e17ced73/
gralde插件/groovy
gradle生命周期
1初始化:根据setting.gradle 和build.gradle实例化progject
2配置阶段 为project配置task任务,并分析依赖关系
3按顺序执行task
工程 D:/PluginDemo
1、通过实现TaskExecutionListener监听每个task的执行时间
void apply(Project project) {
project.gradle.addListener(new TimeListener())
}
2、对编译的class进行字节码注入
class GatherPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
def android = project.extensions.findByType(AppExtension)
android.registerTransform(new GatherTransform(project))
}
}
https://blog.csdn.net/wangzhongshun/article/details/88381058
3、无埋点统计上报
https://www.jianshu.com/p/250c83449dc0
使用DoKits
jni/ndk
kotlin
性能分析工具
下载模块
D://MultiThreadDownloads demo
网络模块
手写图片加载框架
glide
tinker原理,生成patch方法
https://blog.csdn.net/qq_18983205/article/details/83745035
https://blog.csdn.net/qq_22393017/article/details/82110343
组件化,有热修复时注意事项
arouter
https://www.jianshu.com/p/b5be6b896a1a
https://www.jianshu.com/p/857aea5b54a8
https://www.jianshu.com/p/5b35309e9bb2
事件分发
http://allenfeng.com/2017/02/22/android-touch-event-transfer-mechanism/
插件化
换肤
https://www.jianshu.com/p/af7c0585dd5b
https://github.com/fengjundev/Android-Skin-Loader
https://github.com/xbl179909/SkinLoader(自己的demo)
注解
https://www.jianshu.com/p/28edf5352b63
https://www.jianshu.com/p/9471d6bcf4cf
泛型
泛型擦除及带来的问题
https://www.cnblogs.com/wuqinglong/p/9456193.html
shell脚本
sharepreference优化
动态代理
https://www.cnblogs.com/whirly/p/10154887.html
D:\flowLayout
kotlin高级用法
https://blog.csdn.net/qq_15988951/article/details/104918297
let 适用于不为空的情况,相当于it
with 适用于调用当前对象的多个方法时,可以直接书写方法名
run 使用于let\with的所有场景,返回最后一行
apply 适用于run任何场景,不过返回的是对象本身
also 适用于let函数的任意场景,返回对象本身
kotlin使用
7891011版本适配 新特性
数据库设计表 聊天?
加载一百张大图
模板使用问题
属性动画原理总结:
https://www.jianshu.com/p/46f48f1b98a9
https://www.jianshu.com/p/489abbc15241
以ofInt为例子
1、ofInt会生成PropertyValuesHolder,并在内部生成keyFrameset关键帧数据,至少两个关键帧
2、调用start方法后会将objectAnimator(实现了AnimationFrameCallback接口)放入animationHandler的
mAnimationCallbacks数组中(所有动画都在此),如果之前mAnimationCallbacks为空则通过Choreographer注册
vsync信号,在doFrame回调中遍历mAnimationCallbacks中所有动画,执行一帧动画实现。如果该动画执行完成,则将回调
从动画数组中移除,执行完当前帧后判断动画数组如果不为空,继续通过Choreographer注册vsync信号
3、每一帧动画的执行doAnimationFrame(long frameTime):根据vsync信号回调的时间计算fraction,并判断动画是否完成,
如果完成将该动画从动画数组中删除。根据interpolator调整fraction,根据当前fraction所属的前后关键帧区间计算出value
(有evaluator需要根据估值器计算),然后通过反射完成属性set操作完成赋值。
补间动画原理:
通过view.startAnimation启动,里面会执行invalidate,draw方法会执行applyLegacyAnimation,执行animation
的getTransformation()方法(该方法返回是否继续指定动画(是则继续调用parent.invalidate(l,t,r,b))),getTransformation
根据当前时间和起始时间判断动画是否执行完毕,根据插值器计算出时间比例,并调用applyTransformation(int interpolatedtime, transformation t)给transformation设置对应的属性(缩放、透明度等),然后回到applyLegacyAnimation地方,把transfromation
中对应的属性设置给canvas(alpha,其他缩放,旋转等都设置的Matrix)进行变换,所以只是绘制时变换,不是view的属性
不断重复的补间动画导致的关闭onstop执行慢,在onPause时判断isFinish为true则释放资源,
https://mp.weixin.qq.com/s/739xdk57OIp8aYi5aYEWEQ
属性动画不会阻塞主线程的原因?
if (pendingIdleHandlerCount < 0 && (mMessages == null || now < mMessages.when)) {
pendingIdleHandlerCount = mIdleHandlers.size();
}
如果是补间动画mMessages不为空,有同步屏障,所以不能继续执行idelHandler;属性动画只是注册了Vsync信号,所以此时mMessage为空,
可以继续往下执行
圆形头像
https://blog.csdn.net/gdutxiaoxu/article/details/79658621
1\xfermode:先创建原图作为dest,然后创建圆形bitmap作为src,设置paint为des_in,将圆形bitmap画到dest bitmap上,在将dest画到canvas
2\将bitmap设置到bitmapshader上,给paint设置bitmapshader,然后调用canvas.drawcircle(paint)
双指放大实现
public class ZoomListenter implements OnTouchListener {
private int mode = 0;
float oldDist;
float textSize = 0;
TextView textView = null;
@Override
public boolean onTouch(View v, MotionEvent event) {
textView = (TextView) v;
if (textSize == 0) {
textSize = textView.getTextSize();
}
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mode = 1;
break;
case MotionEvent.ACTION_UP:
mode = 0;
break;
case MotionEvent.ACTION_POINTER_UP:
mode -= 1;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
mode += 1;
break;
case MotionEvent.ACTION_MOVE:
if (mode >= 2) {
float newDist = spacing(event);
if (newDist > oldDist + 1) {
zoom(newDist / oldDist);
oldDist = newDist;
}
if (newDist < oldDist - 1) {
zoom(newDist / oldDist);
oldDist = newDist;
}
}
break;
}
return true;
}
private void zoom(float f) {
textView.setTextSize(textSize *= f);
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
}
网友评论