Android 内存泄露

内存泄露的定义:
当某些对象不再被应用程序所使用,但是由于仍然被引用而导致垃圾收集器不能释放(Remove,移除)他们.

产生的原因:

内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)

长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是java中内存泄露的发生场景。

Read more   2016/1/14 posted in  Android

IDEA 技巧

重构

  • Undo Commend + Z undo 是安全的,可以撤销所有 refactor 操作。
  • Find and replace code duplicates 可以选择当前文件,uncommit 文件、项目等 进行替换
  • Rename Shift + Commend + F6
  • Type migration Shift + Commend + F6 改变变量的属性,举个🌰 , 可以将 int -> Long ,需要migration 的是 int 而不是变量
  • Invert boolean
    反转 boolean 型变量值 ,true -> false, false -> true ,同时 rename 变量值
  • safe delete Fn + Commend + Delete 安全删除
  • extract
    提取变量、参数等

  • 提取为参数:Option + Cmd + P 将变量提取到方法中为方法的参数

  • 提取变量为函数名:Option + Cmd + V 将 new 出的对象,提取成一个对象

  • 提取常量:Option + Cmd + C 提取的常量为 static final,TAG快速生成

  • 提取方法:Option + Cmd + M

  • 提取为成员变量:Option + Cmd + F

Read more   2016/1/14 posted in  Android

VIM 技巧

VIM

代码选择

v:选择代码块
V:选择代码行
ctrl+V:多行选中模式 (esc 之后生效)

跳转

  • ):代码快跳转
  • ] :函数跳转
  • } :class 跳转
    ## 移动
  • hjkl
  • f/F: 查找字符
  • t/T: 同上,区别是停留前一个字符
  • gg/G: 文件开头/结尾
  • H/M/L:跳到当前屏幕的顶部/中间/底部。
  • ‘[ 跳到上一次被改变的文本的第一个字符
  • '. 跳到上一次文本被修改的地方
  • '' 跳回上一次跳转的地方
  • '^ 跳到插入模式最后一次结束的地方
    ## 编辑模式
  • x/X是删除当前光标下/光标前的一个字符
  • d/c/y是删除/修改/复制命令

diw, yiw, ciw, viw 删除(复制,改变,选中)光标所在单词
da”, ya”, ca”, va” 删除(复制,改变,选中)””号内所有文本,包括引号本身

  • * 向前查找当前光标下的单词
  • # 反方向查找当前光标下的单词
  • 我们在使用的过程中,会遇到这样的问题,分别在两个地方删除内容,然后需要分别粘贴,这样的情况就需要用到"ayy "ap这样的命令了,"ayy是把当前行复制到名字为a的寄存器中,"ap就是在这里粘帖a寄存器中的内容。
2016/1/10 posted in  Java

Android Media Player

Audio Stream

Android为不同的应用场合定义了不同的Audio Stream: Voice Call, Ring, Music,Alarm, Notification, DTMF。 这些AudioStream是相互独立的,所以也有各自的音量

使用

最重要的类是 MediaPlayer,获取、解码、播放
播放 res/raw 中的文件 举个🌰

MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);
mediaPlayer.start(); // no need to call prepare(); create() does that for you

异步准备

可能需要比较长的时间,media 需要获取资源和解码,最好不要放在 UI 线程。
此时可以使用prepareAsync()方法,这个方法在后台运行,当准备工资就绪之后在MediaPlayer.OnPreparedListener返回,可以在回调函数setOnPreparedListener()中设置

mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        // TODO: 15/10/27  
    }
});
Read more   2015/11/27 posted in  Android

Android View 小结(下)

自定义 view

自定义 view 的主要步骤如下:

  1. 自定义 view 属性
  2. 在 view 的构造方法中,加载自定义的属性
  3. 重写 onLayout
  4. 重写 onMeasure
  5. 重写 onDraw

自定义 view 属性

自定义View的属性,首先在res/values/ 下建立一个attrs.xml

Read more   2015/11/24 posted in  Android

Android service

onCreate()方法只会在Service第一次被创建的时候调用,如果当前Service已经被创建过了,不管怎样调用startService()方法,onCreate()方法都不会再执行。

Read more   2015/10/26 posted in  Android

robolectric

环境搭建

环境 : Android Studio 1.2.1.1+ Android Gradle Plugin 1.2.3+ Gradle 2.2.1+

gradle中加入:

  dependencies {
    ...
    testCompile 'org.robolectric:robolectric:3.0'
  }

确认在Build Variants窗口内的Test Artifact中选择了"Unit Tests"。

然后,在工程的src文件夹内创建test和test/java文件夹。需要注意的是,你不能在Android视图下进行这些操作,要么在系统的文件管理器内创建,要么在工程窗口左上方点击下拉菜单选择Project视图。最终的工程结构应该是这样的:

配置成功之后java文件夹的颜色是绿色的

**重要重要**
Run -> Edit Configurations -> Defaults -> Junit
设置如下 \(MODULE_DIR\).

gradle 同步

注意Robolectric目前不支持android 5.1 API level 22,编译时 sdk = 21 或者以下。

Read more   2015/8/15 posted in  Android

Android Studio中进行单元测试

步骤

新建hello_world工程

配置单元测试

首先,确认在Build Variants窗口内的Test Artifact中选择了"Unit Tests"。

然后,在工程的src文件夹内创建test和test/java文件夹。需要注意的是,你不能在Android视图下进行这些操作,要么在系统的文件管理器内创建,要么在工程窗口左上方点击下拉菜单选择Project视图。最终的工程结构应该是这样的:

配置成功之后java文件夹的颜色是绿色的

最后,打开工程的build.gradle(Module:app)文件,添加JUnit4依赖,点击Gradle sync按钮。

build.gradle中加入依赖

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.1.1'
    testCompile 'junit:junit:4.12'
}
Read more   2015/8/15 posted in  Android

AIDL 学习

AIDL的作用

AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。

选择AIDL的使用场合

官方文档特别提醒我们何时使用AIDL是必要的:只有你允许客户端从不同的应用程序为了进程间的通信而去访问你的service,以及想在你的service处理多线程。

如果不需要进行不同应用程序间的并发通信(IPC),you should create your interface by implementing a Binder;或者你想进行IPC,但不需要处理多线程的,则implement your interface using a Messenger。

如何使用AIDL

先建立一个android工程,用作服务端

创建一个android工程,用来充当跨进程通信的服务端。

2.创建一个包名用来存放aidl文件

创建一个包名用来存放aidl文件,在里面新建IMyService.aidl文件,如果需要访问自定义对象,还需要建立对象的aidl文件,这里我们由于使用了自定义对象Student,所以,还需要创建Student.aidl和Student.java。注意,这三个文件,需要都放在aidl文件夹下com.example.xuyushi.aidltest包里。下面描述如何写这三个文件。

Read more   2015/7/4 posted in  Android

蓝牙学习

权限

有两种权限,至少需要一种权限

  1. BLUETOOTH:执行任何蓝牙通信,例如请求一个连接、接受一个连接以及传输数据
  2. BLUETOOTH_ADMIN:初始化设备查找或控制蓝牙设置

如果你使用BLUETOOTH_ADMIN权限,那么必须拥有BLUETOOTH权限。

Read more   2015/7/1 posted in  Android