2017年度总结( 辞旧迎新)

前言

2017年过去,18年也溜了两个月。春节过完了,把时间挤挤出来总结一下实习以来的收获,还有新的一年的展望吧。

辞旧小结

自定义View

在公司实习这段时间,对自定义 View 有了更多的了解,一些停留在书本上的知识,逐渐转化为了手上的代码能力。

自定义View上最为熟悉的是继承自 VIew ,重写 onDraw 方法,过了一眼扔物线的自定义 View 教程基础部分,基本简单的需求都能画出来了。水平大概停留在 canvas.drawXXX 的使用。

同时对触摸事件。特别是屏幕坐标系,还有 scrollBy / scrollTo ,getRawX / getX 等的基本API差别.虽然在公司中实现的功能,只是重写了 onTouchEvent() 来对触摸坐标的处理,但是这是屏幕事件的基础。长按,滑动等的实现都来自这里的监听。而更高级的事件拦截分发,处理也是这里。

事件拦截分发,或许更适合自定义 ViewGroup。dispatchTouchEvent -> onInterceptTouchEvent -> onTouchEvent 层层拦截判断是否消费,走到 OnTouchEvent 都不拦截消费就传回给 parent 。常说的滑动冲突听过不少,改天找个 demo 来实践一下。

待扩展屏幕坐标系和事件拦截基础,单独写一篇自定义View小结。

SurfaceView

SurfaceView 也算是自定义 View 的一部分。本身他是继承自 View 的。但是他是自己开了个线程进行绘制,与常用的自定义View 不太一样,所以抽取了出来。

SurfaceView 多用于游戏或者视频,由于开了一个子线程绘制,所以基本不会卡顿,而且是被动地,不间断地刷新,不用频繁调用 invalidate() 方法。我是因为公司要做一个引导车辆行驶的指示图,需要随着车辆位置不断刷新,所以选中了他。

基本的使用就是继承 SurfaceView,实现 SurfaceHolder.Callback 接口。

public class MinMapRadar extends SurfaceView implements SurfaceHolder.Callback,Runnable{
  private boolean isDrawing = false;//标记子线程不断刷新
  private Thread drawThread;//绘制线程
  private SurfaceHolder mSurfaceHolder;//控制SurfaceView
  
  private void init(){
    mSurfaceHolder = getHolder();//获取Holder实例
    mSurfaceHolder.addCallback(this);//设置接口
  }
  
    @Override
    public void surfaceCreated(SurfaceHolder holder) { // 创建窗口
      isDrawing = true;
      drawThread = new Thread(this);//实现Runnable接口
      drawThread.start();
    }
  
      @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        //改变
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {//销毁
        synchronized (this) {
            isDrawing = false;
            try {
                drawThread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
  
  @override
  public void run(){
    while(isDrawing){
      if(mSurfaceHolder != null){
        Canvas canvas = mSurfaceHolder.lockCanvas();//获取canvas并锁定
        try{
          if(canvas != null){
            //绘制
          }
        } finally {
          if (canvas != null) {
            mSurfaceHolder.unlockCanvasAndPost(canvas);//释放canvas并提交
          }
        }
      }
    }
  }
}

比较重要的要点都加了注释说明。

由于是子线程绘制,所以在退出销毁的时候,mCanvas为空了,或者 Holder 为空了,所以要注意判空操作,不然会崩溃。另外此处特地在 Destoryed 时候加了 drawThread.join() ,把绘制线程加入主线程顺序执行,可以保证先让 drawThread 停止绘制了才执行销毁操作。

Excel 表格读取

读取 Excel 也是遇到的一个小需求,当然公司里面已经有类似的代码,面向复制编程一下也基本搞定了。

操作是用相对流行的 apache poi 包,可以解析 .xls (2003)、.xlsx (2007) 后缀的 Excel 文件,不过要引入两个不同的包。

poi<-version >.jar —— .xls (2003)

poi-ooxml<-version>.jar —— .xlsx (2007)

操作基本都是获取 sheet,然后通过解析行列获取单元格。

详细读写操作可以参考这篇文章:java 读写 Excel

九宫格缓存

有个需求要给路基压实机行驶过的路段实时监测温度,温度每秒钟采集一次。并且会有覆盖碾压。温度源之间相近的距离会产生印象,时间相近的产生影响。说起来挺复杂的,也不太好说得详细。

总之遇到其中一个难点是一整条公路,我要搜索在屏幕里面的点。由于公路会很长,所以随着行驶距离增加,单纯用链表存储,搜索效率实在太低下了。请教了大佬,利用了类似索引的思想,创建了一个九宫格缓存。

假设设置了九宫格一个格子边长为 20, 那么对于 xy 坐标(30 , 45),除以这个边长。

x = 30 / 20 = 1 (int 型取整) , y = 45 / 20 = 2。

然后创建一个表,表名为 12 。

对于坐标(35,48),同理 x = 35/20=1,y = 48/20=2,那么这个点也在这个表12里面。

这里面每个表就代表一个小格子,一个格子就代表一个20x20的区域。建表同时也把周围八个格子表创建完毕。

在搜索的时候可以根据坐标换算出表名迅速定位到对应的表,即可加载出一个九宫格范围的点。

在做这个需求的时候,了解了RangeQuery,KDTree,RangeTree 等概念,在范围搜索,空间搜索还是很有用处的。但是由于考虑我的情况是一条长长的公路,而不是类似一个城市区域散乱分部,就算做了 RTree 处理,但是树结构上,距离顶点越远的还是搜索的越久,而顶点设置往往就加在路段开始的地方了,毕竟修路没有从中间开始修的。RTree 感觉更适合在宽高差不多的二维空间下,点散乱分布的情况。

线程池和 CountDownLatch 初探

面向复制大佬代码编程的时候接触到线程池和 CountDownLatch。严格来说是 newFixedThreadPool 和 CountDownLatch。在这里做个简单的总结,因为自己并没有了解透彻,所以只是简单描述一下。

Android 中的线程池都是直接或者间接配置 ThreadPoolExecutor 来实现不同特性的线程池

Android 中常见的线程池有四类,FixThreadPool、CachedThreadPool、ScheduleThreadPool以及SingleThreadExecutor。这里只是简单地说 FixThreadPool。

FixThreadPool 是定长的线程池。学过 java 基础都比较容易理解 “ 池 ” 这个概念。线程池说过来也是对线程的重复利用以及定时执行并发控制等的操作。我们常用的 new Thread(Runnable) 匿名实现方式很容易导致无限新建线程,相互间竞争资源,占用资源过多导致死机或者OOM。

FixThreadPool(int nThreads) 属于线程池的一种,自然可以对线程复用管理,而相较于其他几个,它的特性在于定长。传入的参数规定了最大并发数,超出的线程会在队列里面等待。由于线程不会回收,他也会更快地相应外界请求。

ExecutorService executor = Executers.newFixedThreadPool(3);//创建
executor.execute(runner);//执行,实现 Runnable

而 CountDownLatch,是用来并发计数的。举个栗子,当我们解析一个 Excel 表格中的多个 sheet 数据,可以用多线程完成。每个线程解析一个 sheet 数据,所有的线程解析完毕,触发 “ 解析完成事件处理 ”。这个时候就可以用CountDownLatch。CDL 设定一个初值,调用了 await 的线程处于等待,等到 CDL == 0 的时候,await 就会解除,该搞事的继续搞事。

//伪代码如下
ExecutorService executor = Executers.newFixedThreadPool(3);//创建
CountDownLatch cdl = new CountLatch(10);
//这里用线程池
for (int i = 0; i < rdlist.size(); i++) {
  Runnable runner = new analysisThread(sheet,cdl);//自定义Thread
  executor.execute(runner);
}
cdl.await();//这里主线程等待上面10个子线程完成
//“ 解析完毕事件处理 ”

//-------------------------------------------------------------
class LoadDataThread implements Runnable{
  Sheet sheet;
  CountDownLatch cl;
  public LoadDataThread(Sheet sheet, CountDownLatch cl){
    this.sheet = sheet;
    this.cl = cl;
  }
  public void run(){
    //对sheet解析
    cl.countDown();//解析完毕对 cdl - 1 
  }
}

反距离加权插值算法

由于行业原因了解了一下反距离加权插值,还有 RGB 插值。其实就是抄个公式而已。只是深刻体会到,编程往往离不开数学,总有一些效果的实现,前人总结的算法很好使。数据结构算法乃至高等数学线性代数图形学,行业总会与数理化息息相关。证明原理可以不懂,但是公式要看懂,要会用。

renderscript 研究失败

RenderScript 本身其实是用来图像处理中的计算。其实我并没有用到图像处理,只是想着他能够提高计算模块的速度,就拿来用一下。只是一来不太熟悉 C 语言,二来是其异步的设计不太方便返回值,导致我在运用的时候很难得到想要的数据。而且不能 debug ,多次尝试之下还是放弃使用 RenderScript。


迎新展望

毕竟新的一年了,就算是咸鱼总会难免生出一股:新的一年新的自己,相信自己会更好的感觉。所以还是立一下 flag。

  • 搞好我的毕设,为大学画上句号。
  • 日常断更的博客捡起来,多总结多分享(起码一月一篇吧 /笑哭
  • 一个月读一本书
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容