Scroller.startScroll之后要invalidate才可以生效
2016年12月3日09:23:45(for 12.2) 1
- java里面的数字类型,float(1.23)的另一种写法更好一些:1.23f.
- 一个对象可能有多种状态,每种状态有若干种操作的时候,可以采用如下形式:然后通过getStatus获取状态,是一种比较好的设计模式(虽然我不知道这个名字是什么)
public abstract class Status{
abstract public int f1();
public static Status getStatus(int code){
//...
}
public static class StatusA extends Status{
@override
public int f1(){
//impl
}
}
public static class StatusB extends Status{
@override
public int f1(){
//impl
}
}
}
- connection池的实现:一个x大小的set,如果有connection.close()之后不释放,而是放到这个set里面,如果set size超过x就释放,否则就加进去.
- connection.close如果要不释放的话,可以用代理模式加一层封装,在close的时候完成放入池中的判断
- 注意若干个synchronized操作
2016年12月05日23:16:45 2
- AsyncTask是串行的
- AsyncTask包括onPreExecute,onProgressUpdate,doInBackground
- JavaScript里面没有int/float/double之分,只有一个number
- linux
- zsh中ctrl+A/E/W分别是光标最前/光标最后/删除光标前面的单词
- Windows+D可以快速返回桌面
- others
- android的webView可以被JS注入攻击,别人都知道这些了你还在纠缠于view的drawCircle.
- postgresql安装复杂
- git的ssh地址是git@github.com:[NAME]/[repository_name].git
2016年12月06日22:13:16 4
- linux Ctrl+U可以清楚当前命令行中的已输入内容
- android线程
- ThreadService比一般线程可靠,因为是service
- asyncTask是可以通过一个参数配置并行的
- ThreadPoolExecutor有四种CFSS,CachedThreadExecutor(没有core thread,无限多nonCore thread,完了以后过一段时间就走了。适用于10000个*1s的线程情况);Fixed(core thread固定,没有nonCore,中规中矩);Sheduled(core固定,也可以家nonCore,一般用来做定时器,适用情况未知);Single(1个core,保证执行内容的同步).
- ThreadPool中core thread是不会被释放的thread,nonCore是有可能会被释放的thread.
- 比较复杂的系统里面(搞不清楚某个函数的调用时机),如果这个函数可以用标记位标记状态,那么增加一个标记位可以减少复杂性(因为多次进入影响也不大,在函数里面判断状态在进行操作即可)
2016年12月07日18:37:57 5
- View绘制
- Shader设置渐变效果,有SweepGradient,Linear,Radio.
- drawArc只会画出扇形,画有宽度的弧线,要么画俩扇形(前一个有颜色,第二个覆盖住),要么用path,path.arcTo。
- scroller.fling以后要invalidate(跟startScroll一样),不然就算有时候会有滑动的效果,那也是fling用的时间太长,过了16ms才VSYNC自动draw的。时间太短的话,就看不到滑动效果了。
- BitmapLoader
- Bitmap的自适应加载–先用BitmapFactory.decode的Option获取其width,height,然后设置option的取样率(根据bitmap的height/width和view的width/height得到).
- lruCache需要设置cache的总容量和每个存储元素的大小.
- lruDiskCache需要一个key来关联文件,通过获得其iostream来进行文件的读写.
2016年12月08日23:48:00 3
还要看比赛晚睡咯囖囖囖
- 加载文件/图片/音频等的几大部分大概有
- 缓存。LruCache和LruDiskCache
- LruCache:new<K,V>;put(key,value);get(key);
- LruDiskCache:LruDiskCache.open(file…);edit(key);editor.newOutputStream();editor.commit();editor.abort();flush();getSnapShot(key);snapshot.getInputStream();
- 同步/异步.
- 同步:Looper.getMainThreadLooper()判断是不是主线程;
- 异步:另开线程需要结合线程池进行,以对线程进行管理。同时图片加载还需要注意View的复用,可以在加载前设置tag,加载后通过view的tag判断是不是正确的加载目标。
- UncaughtExceptionHandler,通过Thread的静态方法get/setDefaultExceptionHandler可以对未作处理的crash进行捕获处理(然后程序还是会崩溃,但是可以在崩溃前主动kill自己,commit suicide),保存log,上传log等。
- 方法数65535了以后,在gradle/Application里面加上multiDex的相关语句,可以在打包的时候打成俩dex,就避免爆表了。可以在gradle里面加语句控制什么类加载到main Dex,如果加载了第一个dex,执行里面代码的时候还没有加载第二个dex,程序就crash了,ClassNotFound。
- 插件化要注意的部分:
- 资源读取,反射通过loadResources(file)(不知道哪个类里面的,file是新的dex文件)获取。然后就可以R.什么什么了。
- activity生命周期管理(???为什么管理呢?),反射或者接口。(插件化好像需要代理activity才可以调用别的dex里面的activity????)
- 多个dex的嘶吼,需要多个classLoader,可以用hashMap<dexPath,ClassLoader>
- 反编译用到的:dex2jar,jd-gui(AS应该也可以),apktool可以获取资源文件(dex2jar获取不到,只能获取src代码)
2016年12月10日18:42:07 6
有些事情,坚持下去就是奇迹了。
- jni的步骤
- handmark的pullToRefresh框架中的PullToRefreshBase类有BUG:在它内部的adapter中的数据量为0的时候,就直接响应下拉手势了,其实可能这时候headerView还没有到顶,作者没有考虑到headerView和footerView长度比较长的情况。
2016年12月14日23:35:43 2
上面的写错了,上面的前半部分是jni,后半部分成了ndk了。
- jni
- java中native声明->javac javah生成.h->编写.c实现.h->用gcc编译共享库生成.so->java命令增加so目录参数运行java程序
- ndk
- java声明native->编写.c和Android.mk->ndk build(需要放对目录)生成.so->.so放到android项目的指定目录/jni代码放到指定目录????->build即可将.so打包到apk
- JNI的参数类型:jstring jobject 等,具体不写了
- JNI调用java函数
- Env*获取class->class通过方法名,方法签名获取方法id->通过调用方法函数调用方法
- 软件开发
- 一个好的准确的过程类比(metaphors)可以模糊完整的描述一个事情。例如软件开发和盖房子。
- 问题提出和需求分析是在构建代码(construction)之前的两个模块。
2016年12月16日00:23:42(for 12.15) 3
- 软件设计这个东西吧,有点虚。不像公式算法,有特定的步骤。这东西有点文艺。
- 系统设计的时候注意减少复杂度(complexity,即思考问题时候的要保存在大脑内存里的东西的多少)。
- 减少复杂度的方法:层次化
- (系统层次system,子系统subsystem/package,类class,子程序routine/method,具体算法),分层设计思考的时候只用着眼当前层次,避免过多要兼顾的东西引起BOOM(Brain Out Of Memory)。
- package层次上分为不同的package,应当限制各个subsystem之间的通信,不然会导致系统熵(entropie)的增大—-也就增加了设计的复杂度。
- 更加低层次的(class层次)的减少复杂度的方法。
- 类关系。抽象/继承/属性隐藏(private)/类型隐藏/访问器限制(不允许直接获取,通过方法返回值获取)。重点在于信息隐藏(information hiding),这样可以1.易于维护(调用代码的人拿到对象后并不能随意修改,日后维护容易,否则需要对每个调用了代码的地方进行修改).2.易于开发(调用代码的人可操作的东西少了,关注的东西更加集中,方便理解)
- 类实现,设计模式。设计模式有很多,我都不知道。设计模式的使用可以方便开发(”我这里用了bridge”,”懂了” vs. “我这里是这样子的,^^&^$%^*(&(“,”???”.)。同时设计模式也是非常好的实现方法(经过了历史的洗礼,有理由相信这一点。)
2016年12月19日18:30:54 4
- 设计有点虚头巴脑的好像。。。
- 实际设计的时候不好考虑,方向可以使自下而上/自上而下。各有各的好处,提高团队设计能力的方法还有CRC(class,response,corparate?)卡片……感觉代码大全不是技能书啊ORZ,是个大纲啊熊迪。可能是前面的”设计”这个章节确实难以表达,只能凭借经验“启发式”heuristic…
2016年12月20日18:30:32 1
- class的设计
- 抽象化abstract(类暴露的方法和数据尽量的可以描述这个class,并且没有让人觉得看起来蓝瘦的地方。)
- 数据隐藏(对外/对子类,private,final等)
- 增强方法可读性,减少方法的语义相关性(android这方面很多类的设计不完美,很多类都需要先A.a();才能A.b();并且默认你知道应该这样子做。其实安卓开发或者说这些框架开发大部分要写的东西不能算是类设计,所以可能为了防止过于复杂,就这样子了。)
- 既然面向对象了,尽量保证代码可读性。
- 多重继承可以用包含第二个parent class实现。
- 为什么使用面向对象class
- 降低复杂度(面向过程的开发导致需要考虑的东西过多,面向对象可以分割思考的范围,这也使程序开发最重要的地方;同时隐藏部分数据和方法;控制代码集中(例如数据库的操作);)
- 方便替换(替换影响的东西很少)
- 复用
- 代码大全是本好书,讲了很多可以引发思考的东西
2016年12月21日18:38:20 4
- 软件设计
- 子程序的设计可以降低复杂度(思考的时候可以直接讲子程序作为一个单位进行思考,从而降低复杂度);复用;便于维护。
- JVM
- 在new对象以后,加载类,分配空间,初始化。
- JVM需要知道一个对象对应的类。有一种方式是对象头部(像文件一样,有一个头部包含一些基本信息)包含有对象的类在方法堆中的地址信息。
- OOM包含堆OOM,栈OOM。
2016年12月22日22:24:29 2
JVM(code complete 毕竟是软件开发的呀。。。消化不好)
- 对象何时GC
- 引用计数:有来自其他对象的引用时+1,来源被GC的时候-1。简单易懂/循环应用大BUG
- 可达性分析:GC roots是否可达。
- GC roots:方法栈(虚拟机栈/native方法栈)中的对象/永久代中的对象(静态/常量),等
- GC与清除:GC后彻底清除之前会挨个调用待GC对象的finalize,之后再判断是否要清除。如果在finalize中有一句x=this;则可以挽留一下对象。一个对象的finalize只会被JVM调用一次,第二次GC后如果发现已经调用过finalize便不会再次调用,直接清除。
- JVM的GC方式
- 标记-清除mark-sweep。简单中庸/内存碎片化
- 复制。没有内存碎片/内存利用率只有一半,与GC率(就是一次GC能清除的内存比例)关系不大,GC成本稳定
- 标记-整理。内存完全利用,没有内存碎片/GC平均成本高,内存改动频繁,GC率高的时候移动内存成本高。
- JVM如何GC
- 在哪里?JVM需要保证所有的线程”安全地静止”。所以每个线程都有一些safe region,线程到达region后判断是否准备gc,如果准备gc就自己暂停,过一段时间再恢复。
- GC roots都有谁?JVM管理的内存区域很大,每次都挨个寻找gc roots也非常消耗时间,所以JVM会提前知道——有的在编译出来的代码栈中表明这里有GCroot,有时候是别的方法。
- GCer
- young generation:
- Serial。简单,适合单核处理器/单线程,程序暂停很明显。
- ParNew。简单,多线程/程序暂停明显。
- Parallel。多线程,目标是降低吞吐量,程序整理效率高/有些情况下GC时间也长。
- old generation:
- Old Serial。简单,单核处理器/单线程,程序暂停明显。
- Parallel。多线程,目标是降低吞吐量,整理效率高/有些GC时间高
- CMS(Concurrent Mark Sweep)。高端,多CPU时程序基本可以跟GC并行( CMS分为四部分:标记1(GC初始标记,只标记GC roots近的,此阶段线程封锁),标记2(线程不封锁,标记线程运行中的其他对象),标记3(线程封锁,标记线程运行中标记1里面改变了的),清理4(线程不封锁)。1,3占用时间短)/MS会有内存碎片
- young generation:
2016年12月26日18:45:26 5
- G1是一个分区的GCer,在GC的时候优先GC那些GC率高的区域(Garbage First,不过怎么知道哪个区GC率高?)。不产生碎片。缺点是很复杂。
- JVM分代内存分配
- 新对象放到eden(young generation)中
- 对象从eden进入到old generation的条件:
- 新对象太大,eden里面放不下
- eden里面的对象到了一定年龄(eden采用copying,每次copy一次,所有survivor年龄+1,到了一定年龄(可以在VM option里面设置)就被移入old generation)。
- eden快满了(例如:eden里面超过一半空间对象年龄都是x,比x大的都移入old generation)
- edenGC了一次以后还是放不下,就把一部分放到old generation中。
- 服务器端的java service可以通过设置合适的jvm option来定制以提升性能。比如堆内存大小,等。(不懂,很不懂。)
- JVM与class文件
- JVM只认识class文件,class文件不一定是java编译出来的。jython等语言也可以生成。JVM跨语言跨平台连接你我。
- class文件是一个文件,有一定的格式
- class的MAGIC字段是CAFEBABY。:)
2016年12月27日18:31:47 5
JVM class文件格式
- 常量区
- 基本类型常量/所有class的全称/所有方法常量/属性常量
- flag区
- public/private/protected/abstract/final/volatile/…等区域
- 父类在常量区的索引/接口在常量区的索引
- field区
- 包含当前类的成员变量信息,成员变量的private/public/protected/final等标志,成员变量类型在常量区的索引,成员变量的名字在常量区的索引.
- (Nullable)在属性区的初始值的索引等。
- method区
- 方法的名字在常量区的索引
- 方法的签名((CI)[I;)在常量区的索引
- 方法的public/private等flag。
- attribute字段:
- 在属性区的字节码的索引
- 方法用到的局部变量空间的大小(方法栈的大小,编译时候确定)
- 属性区
- 属性区很复杂很乱,包含的东西很多,字节码/代码行号/运行异常/等
- 字节码
- 字节码长度(方法长度是有限制的,超过了以后编译异常)。
- 类似于汇编的代码,一个字节码占2Byte,就是说最多有0~256种码,已经用了的有200+。
2016年12月28日23:12:08 4(too late)
前面有几点错了
- class文件格式里面的属性区(attribute)可以作为字段区(field区)或者方法区的子区域,或者作为class文件的子区域(与方法区同级的)。在字段区的最后有个属性区表示字段常量值,在方法区最后有个属性区表示字节码等。
- 属性区有多种属性,字节码/异常信息/字节码行号/局部变量名字混淆/内部类/等信息。
- android可以通过Manifest里面多个activity-alias标签来指定多个程序入口,然后在代码里面通过Packagemanager的setComponentEnabled来进行桌面launcher的删除/添加,完成动态改变程序运行icon的功能。
2016年12月29日22:29:47 5
- class字节码跟汇编挺像的
- JVM读取class字节码(Code区)使用的是数据栈而不是寄存器操作。所以数据有load,store的加载/存储方式。还包括有别的,比如数据的运算(比较/加减乘除);对于不同的数据类型(int,float,double等)也有不同的字节码比如iload,fload,dload;
- Excel里面的删除线是一种格式,跟下划线/加粗一个性质
2016年12月30日19:15:04 4