Ragnarok Note

Articles in the Android category

如何获取Android系统中申请对象的信息

最近一直在做有关内存方面的优化工作,在做优化的过程,除了关注内存的申请量以及GC的情况之外,我们经常需要想方法找出是那些对象占用了大量内存,以及他们是如何导致GC的,这意味着我们需要获取对象申请的信息(大小,类型,堆栈等),我们这篇文章来介绍下几种获取对象申请信息的方法

Allocation Tracker

Allocation Tracker是android studio自带的一个功能,我们可以在MemoryMonitor中打开使用:

如上图,点击红框按钮,然后操作app,开始allocation tracking,当认为需要结束的时候,再次点击按钮,稍等片刻,即可以在android studio中dump出在 这段时间新申请 对象的信息:

这种使用方式相当直观,可以看到申请对象大小,数量,还有堆栈等,通过这些信息,我们可以作为我们接下来进行内存优化的参考

但是,对于这种获取申请对象信息的方法,会存在几个问题:

  1. 获取的信息过于分散,中间夹杂着不少其他的信息,不完全是app申请的,可能需要进行不少查找才能定位到具体的问题
  2. 跟TraceView一样,无法做到自动化分析,每次都需要开发者手工开始/结束,对于某些问题的分析可能会造成不便,而且对于批量分析来说也比较困难
  3. 虽然在allocation …

Tricking Android MemoryFile

之前在做一个内存优化的时候,使用到了MemoryFile,由此发现了MemoryFile的一些特性以及一个非常trickly的使用方法,因此在这里记录一下

What is it

MemoryFile是android在最开始就引入的一套框架,其内部实际上是封装了android特有的内存共享机制Ashmem匿名共享内存,简单来说,Ashmem在Android内核中是被注册成一个特殊的字符设备,Ashmem驱动通过在内核的一个自定义slab缓冲区中初始化一段内存区域,然后通过mmap把申请的内存映射到用户的进程空间中(通过tmpfs),这样子就可以在用户进程中使用这里申请的内存了,另外,Ashmem的一个特性就是可以在系统内存不足的时候,回收掉被标记为"unpin"的内存,这个后面会讲到,另外,MemoryFile也可以通过Binder跨进程调用来让两个进程共享一段内存区域。由于整个申请内存的过程并不再Java层上,可以很明显的看出使用MemoryFile申请的内存实际上是并不会占用Java堆内存的。

MemoryFile暴露出来的用户接口可以说跟他的名字一样,基本上跟我们平时的文件的读写基本一致,也可以使用InputStream和OutputStream来对其进行读写等操作:

MemoryFile memoryFile = new MemoryFile(null, inputStream.available());
memoryFile.allowPurging(false);
OutputStream outputStream = memoryFile.getOutputStream();
outputStream …

RxCamera, 一个RxJava风格的android camera封装

事实上这个库写了已经有一段时间了,由于最近工作上比较忙,所以现在才写一篇文章来总结

What's this

正如标题所说,RxCamera是一个基于RxJava而构建的一套android.hardware.camera封装的库。最初写这个库的目的是为了熟悉RxJava,并且而且也看到虽然在android开发已经有不少基于RxJava的库,但是关于音视频相关却少之又少,于是就动手实现了一下。目前这个库还处于非常早期的状态,API比较简陋,并且关于camera的设置还有很多没有做

How to use

RxCamera的README中已经有关于这个库使用的比较详细介绍了,我在这里再说明一下:

加入依赖

首先你需要在项目中加入对RxCamera项目的依赖:

repositories {
        jcenter()
}
dependencies {
    compile 'com.ragnarok.rxcamera:lib:0.0.1'
}

基本的使用

  • 配置camera的参数

android的原生camera api提供了不少的选项来配置打开摄像头时候的参数,例如预览的帧率,预览的分辨率,自动对焦等,在RxCamera中主要是通过一个RxCameraConfig对象来管理这些对象,并通过 …

TextView预渲染研究

Android中的TextView是整个framework中最复杂的控件之一,负责Android中显示文本的大部分工作,framwork中的许多控件也直接或者间接的继承于TextView,例如Button,EditText等。其内部实现也相当复杂,单论代码行数来说,android-22中TextView有足足9509行,另外,TextView中许多操作都非常繁重,例如setText操作,需要设置SpanWatcher,或者需要重现创建一个SpannableString,还需要根据情况重新创建Text Layout,这些操作加起来之后令一次setText操作非常耗时。为了提升TextView的渲染效率,最近研究了一下预渲染的方法,接下来给大家讲解一下原理。

TextView渲染基本原理

首先来介绍下TextView的基本渲染原理,总的来说,TextView中负责渲染文字的主要是这三个类:

  1. BoringLayout
    主要负责显示单行文本,并提供了isBoring方法来判断是否满足单行文本的条件。

  2. DynamicLayout
    当文本为Spannable的时候,TextView就会使用它来负责文本的显示,在内部设置了SpanWatcher,当检测到span改变的时候,会进行reflow,重新计算布局。

  3. StaticLayout
    当文本为非单行文本,且非Spannable的时候,就会使用StaticLayout,内部并不会监听span的变化,因此效率上会比DynamicLayout高,只需一次布局的创建即可,但其实内部也能显示SpannableString,只是不能在span变化之后重新进行布局而已。

另外,以上三个类都继承于Layout类,在此类中统一负责文本的具体绘制,在Layout …

使用Kotlin进行Android开发

What is Kotlin

Kotlin,原意是在俄罗斯的一个小岛,JetBrain在2011年推出了以这个来命名的一个运行在JVM上的语言, 看上去有点类似C#和Scala的结合,并且同为静态类型,作为一门JVM上的语言,可以轻松兼容Java,并且整个语言设计的非常轻量。目前的版本为0.12.200,尚未发布正式版。


Kotlin的下载和配置在其官网上有,在这里就不再赘述了,值得一提的是,作为JetBrains家出品的语言,自家的IDEA当然全力支持!

基本语法介绍

Kotlin的语法非常简洁,熟悉Java或者Scala的人都可以快速上手:

函数声明:

fun foo(va: Int): Int {
    return 1
}

也可以单行声明:

fun foo(va: Int): Int = 1

lambda当然也是支持的:

var c = {foo: Int -> println(foo …