LeoHe's Space

我们是共产主义接班人

[TOC]

写在前面

AUIL 的特点

  • 多线程下载图片(同步异步)
  • 提供多种ImageLoader的用户配置(thread executors, downloaders,decoder, memory and disk cache, display image options, etc.)
  • 为每一个显示图片的调用提供了非常丰富的配置(stub image, caching switch, decoding options, Bitmap processing and displaying, etc)
  • 提供图片的内存和文件缓存
  • 图片加载的监听和下载进度的监听
Read more »

[TOC]

Android JNI 基本知识

1.1 什么是JNI

JNI (Java Native Interface),它提供了若干API使得Java可以和其他语言互通,是JDK的一部分.

理解这些就可以了!

Read more »

[TOC]

Andorid IPC

Android中的多进程模式

1. 开启多进程模式

在Android中,开启多进程的方式是给四大组件(静态注册),加上process属性,让其运行在其他进程,默认的进程的名称为包名.

Read more »

[TOC]

Groovy :MOP与元编程

在Java中,使用反射可以在运行时探索程序的结构,以及程序的类,累的方法,方法接受的参数.然而,我们仍然局限于所创建的静态结构.我们无法在运行时修改一个对象的类型,或是让它动态获取行为–至少现在还不能.如果可以基于应用的当前状态,或者是基于应用所接受的输入,动态地添加方法和行为,代码就会变得更加灵活,我们创造力和开发效率也会提高.那么Groovy就是提供了这一功能

*元编程(metaprogramming)*意味着编写能够操作程序的程序,包括操作程序自身.像Groovy这样的动态语言通过元对象协议(MetaObject Protocal, MOP)提供了这种能力.利用Groovy的MOP,创建类,编写单元测试和引入模拟对象都是很容易的.

在Groovy中,使用MOP可以动态的调用方法,甚至可以在运行时合成类和方法.该特性让我们有这种感觉:对象顺利地修改了它的类.

讨论两个方面:Groovy对象的组成和Groovy如何解析Java对象和Grooy对象的方法调用.

探索元对象

Groovy 对象

Groovy对象是带有附加功能的Java对象.在Groovy中,Groovy对象比编译好的Java对象具有更多的动态行为.

在一个Groovy应用中,我们会使用三类对象:POJO,POGO和Groovy拦截器.

查询方法和属性

调用一个方法

1
2
3
4
5
str = "hello"
methodName = 'toUpperCase'

methodOfInterest = str.metaClass.getMetaMethod(methodName)
println methodOfInterest.invoke(str)

respondsTo方法判断是否存在方法

1
2
3
4
str = "hello"
println String.metaClass.respondsTo(str,'toUpperCase') ? 'yes' : 'no' //yes
println String.metaClass.respondsTo(str,'compareTo',"test") ? 'yes' : 'no' //yes
println String.metaClass.respondsTo(str,'toUpperCase', 5) ? 'yes' : 'no' //no

动态的访问对象

除了前面介绍的方法和属性的查询方式和动态调用方式,Groovy还有其他比较方便的访问属性和调用方法的方式.一下为例子.

1
2
3
4
5
6
7
8
9
10
11
12
def printInfo(obj){
usrRequestedProperty = 'bytes'
usrRequestMethod = 'toUpperCase'

println obj[usrRequestedProperty]
println obj."$usrRequestedProperty"

println obj."$usrRequestMethod"()
println obj.invokeMethod(usrRequestMethod,null)
}

printInfo 'hello'
1
2
3
4
[104, 101, 108, 108, 111]
[104, 101, 108, 108, 111]
HELLO
HELLO

要迭代一个对象的所有属性,我们可以使用properties属性(或者getter)

如下:

1
2
3
'hello'.properties.each {
println it
}

使用MOP拦截方法

在Groovy中可以非常方便的实现AOP编程,比如方法拦截或者方法建议.before advice | after advice | around advice.

使用GroovyInterceptable拦截方法

如果一个Groovy对象实现了GroovyInterceptable接口,那么当调用改对象上的任何一个方法时,不管是存在的还是不存在的,被调用的都将是invokeMethod().也就是说,GroovyInterceptable的invokeMethod方法劫持了该对象上的所有方法调用

如果想要实现环绕建议,只需要在这个方法内实现我们的逻辑.然而想实现前置逻辑或后置建议或者both,我们首先要实现自己的前置/后置逻辑,然后在恰当的时机路由到真实的方法,要路由调用,我们将使用MetaMethod,它可以从MetaClass获得

ps:

对于其他Groovy对象(没有实现上述接口的,只有调用到不存在的方法的时候才会调用该方法.有个例外,如果我们在一个对象的MetaClass上实现了invokeMethod不管方法存在与否,都会调用到该方法.

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Car implements GroovyInterceptable{
def check(){
System.out.println("check called ...")
}

def start(){
System.out.println("start called ...")
}

def drive(){
System.out.println "drive called"
}

def invokeMethod(String name, args){
System.out.println "Called to $name intercepted"
if (name != 'check'){
System.out.print('running filter')
Car.metaClass.getMetaMethod('check').invoke(this,null)
}
def validMethod = Car.metaClass.getMetaMethod(name,args)
if (validMethod != null){
validMethod.invoke(this,args)
}else{
Car.metaClass.invokeMethod(this,name,args)
}
}
}

car = new Car()
car.start()
car.drive()
car.check()
try {
car.speed()
}catch (e){
println e
}

1
2
3
4
5
6
7
8
9
10
11
12
13
Called to start intercepted
running filtercheck called ...
start called ...
Called to drive intercepted
running filtercheck called ...
drive called
Called to check intercepted
check called ...
Called to speed intercepted
running filtercheck called ...
groovy.lang.MissingMethodException: No signature of method: Car.speed() is applicable for argument types: () values: []
Possible solutions: sleep(long), sleep(long, groovy.lang.Closure), split(groovy.lang.Closure), check(), start(), inspect()

使用MetaClass拦截方法

使用GroovyInterceptable拦截了方法的调用,这种方式适合拦截作者是我们自己的类中的方法.然而,如果我们无权修改类的源代码,或者这个类是个Java类,就行不通了,此外,我们也可能在运行时决定基于某些条件或应用状态开始拦截调用,对于这几种情况,我们可以在MetaClass上实现invokeMethod()方法,并以此来拦截方法.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class Car{
def check(){
System.out.println("check called ...")
}

def start(){
System.out.println("start called ...")
}

def drive(){
System.out.println "drive called"
}
}

Car.metaClass.invokeMethod = {
String name, args ->
System.out.println("Call to $name intercepted ... ")
if (name != 'check'){
System.out.print"Running filter"
Car.metaClass.getMetaMethod('check').invoke(delegate,null)
}

def validMethod = Car.metaClass.getMetaMethod(name,args)
if (validMethod != null){
validMethod.invoke(delegate,args)
}else {
Car.metaClass.invokeMissingMethod(delegate,name,args)
}
}

car = new Car()

car.start()
car.drive()
car.check()

try {
car.speed()
}catch (e){
println e
}

[TOC]

面向对象

变量声明范例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class SomeClass {
public fieldWithModifier
String typedField
def untypedField
protected filed1, filed2, filed3

static ClassFiled

public static final String CONSTA = 'a', CONSTB = 'b'

def someMethod(){
def localUntypedVar = 1
int localTyoedVar = 1
def localVarWithoutAssignment, andAnotherOne
}
}

def localVar = 1 //脚本声明变量
boundVar = 1

def someMthod(){
localMethodVar = 1
boundVar2 = 1
}


1
2
3
4
5
6
7
8
9
10
11
//定位字段
class Counter{
public count = 0
}

def counter = new Counter()
counter.count = 1
assert counter.count == 1
def fieldNam = 'count'
counter[fieldName] = 2
assert counter['count'] == 2

方法声明

方法返回值声明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class SomeClass{
static void main(args){
def some = new SomeClass()
assert 'hi' == some.publicUntyedMethod()
assert 'ho' == some.publicTypedMethod()
combineMethod()
}

void publicVoidMethod(){}
def pubicVoidMethod(){
return 'hi'
}
String publicTypedMethod(){
return 'ho'
}
protected static final void combineMethod(){}
}

方法参数声明

1
2
3
4
5
6
7
8
9
10
11
12
13
class SomeClass{
static method(arg){
println 'untyped'
}

static method(String arg){
println 'typed'
}

static method(arg1, Number arg2){
println 'mixed'
}
}

高级方法参数使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Summer{
def sumWithDefaults(a,b,c = 0){
return a + b + cs
}

def sumWithList(List args){
return args.inject(0){
sum,i ->
sum += i
}
}

def sumWithOptionals(a, b, object[] optionals){
return a + b + sumWithList(optionals.toList())
}

def sumNamed(Map args){
['a','b','c'].each{
args.get(it,0)
}
return args.a + args.b + args.c
}
}

构造函数

位置参数

1
2
3
4
5
6
7
8
9
10
11
12
class VendorWithCtor {
String name, product

VendorWithCtor(name,product){
this.name = name
this.product = product
}
}

def first = new VendorWithCtor('canoo','ULC') // Normal constructor use
def second = ['Canoo', 'ULC'] as VendorWithCtor // Coercion with as
VendorWithCtor third = ['Canoo', 'ULC'] // Corecion in assignment

命名参数

1
2
3
4
5
6
7
8
9
10
class Vendor{
String name, product
}
new Vendor()
new Vendor(name: 'Canoo')
new Vendor(product: 'ULC')
new Vendor(name: 'Canoo', product: 'ULC')

def vendor = new Vendor(name: 'Canoo')
assert 'Canoo' == vendor.name

隐式构造函数

1
2
3
4
java.awt.Dimension area
area = [200,100]
assert area.width == 200
assert area.height == 100

属性获取设置器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class MyBean{
def a
def b

def getA(){
return a
}

def getB(){
return b
}

def setA(a){
this.a = a
}

def setB(b){
this.b = b
}
}

def mb = new MyBean()
mb.a = 10
mb.b = 30

属性获取方法,Groovy方式直接.属性名就可以了.

Java Groovy
getPropertyName propertyName
setPropertyName(value) propertyName = value

属性获取器和@语法的使用区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class MrBean{
String firstName, lastName
String getName(){
return "$firstName $lastName"
}
}

def bean = new MrBean(firstName: 'Rowan')
bean.lastName = 'Atkinson'

//advanced accessors with groovy

class DoubleBean{
public value //visible value

void setValue(value){
this.value = value //inner field access
}

def getValue(){
value * 2 //inner field access
}
}

def bean2 = new DoubleBean(value: 100)
assert 200 == bean2.value //Property access use getter method
assert 100 == bean2.@value // Outer field access directly access

GPaths查询对象

invoke example for Gpath

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class Book {
String name
List authors
}
class Author {
String name
Address addr
}
class Address {
String province
String city
}

def addr1 = new Address(province:'Guangdong',city:'Shenzhen')
def addr2 = new Address(province:'Gunagdong',city:'Guangzhou')
def addr3 = new Address(province:'Hunan',city:'Changsha')
def addr4 = new Address(province:'Hubei',city:'Wuhan')
def books = [new Book(name:'A glance at Java',authors:[new Author(name:'Tom',addr:addr1)]),
new Book(name:'Deep into Groovy',authors:[new Author(name:'Tom',addr:addr1),new Author(name:'Mike',addr:addr3)]),
new Book(name:'A compare of Struts and Grails',authors:[new Author(name:'Wallace',addr:addr4),new Author(name:'Bill',addr:addr2)]),
new Book(name:'learning from Groovy to Grails',authors:[new Author(name:'Wallace',addr:addr3)])]

//目标是找到作者是"Tom"的书籍的书名
//Java风格
def booksOfTomOldWay = []
books.each {
def book = it
def aus = it.authors

aus.each {
au->
if (au.name == 'Tom')
booksOfTomOldWay << book.name
}
}

println booksOfTomOldWay
//Groovy风格 非常简练,也符合一个正常的思考顺序.

def booksOfTom = books.grep{
it.authors.any{
it.name == 'Tom'
}
}.name

println booksOfTom

空操作安全

1
2
Duck duck = new Duck()
duck?.eat() // ?.标识如果对象是一个空值,那么久不调用函数.只有非空对象才会执行函数的调用
0%