manifest>
<!-- Include following permission if you load images from Internet --><uses-permissionandroid:name="android.permission.INTERNET"/><!-- Include following permission if you want to cache images on SD card --><uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
...
</manifest>
config imageloader and initial
publicclassMyActivityextendsActivity{@OverridepublicvoidonCreate(){super.onCreate();// Create global configuration and initialize ImageLoader with this config
ImageLoaderConfiguration config =newImageLoaderConfiguration.Builder(this)....build();
ImageLoader.getInstance().init(config);...}}
Display Options
// DON'T COPY THIS CODE TO YOUR PROJECT! This is just example of ALL options using.// See the sample project how to use ImageLoader correctly.
DisplayImageOptions options =newDisplayImageOptions.Builder().showImageOnLoading(R.drawable.ic_stub)// resource or drawable.showImageForEmptyUri(R.drawable.ic_empty)// resource or drawable.showImageOnFail(R.drawable.ic_error)// resource or drawable.resetViewBeforeLoading(false)// default.delayBeforeLoading(1000).cacheInMemory(false)// default.cacheOnDisk(false)// default.preProcessor(...).postProcessor(...).extraForDownloader(...).considerExifParams(false)// default.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)// default.bitmapConfig(Bitmap.Config.ARGB_8888)// default.decodingOptions(...).displayer(newSimpleBitmapDisplayer())// default.handler(newHandler())// default.build();
Usage
可接受的的URI资源示例
"http://site.com/image.png" // from Web
"file:///mnt/sdcard/image.png" // from SD card
"file:///mnt/sdcard/video.mp4" // from SD card (video thumbnail)
"content://media/external/images/media/13" // from content provider
"content://media/external/video/media/13" // from content provider (video thumbnail)
"assets://image.png" // from assets
"drawable://" + R.drawable.img // from drawables (non-9patch images)
NOTE: Use drawable:// only if you really need it! Always consider the native way to load drawables - ImageView.setImageResource(...) instead of using of ImageLoader.
简单使用
// Load image, decode it to Bitmap and display Bitmap in ImageView (or any other view // which implements ImageAware interface)
ImageLoader imageLoader = ImageLoader.getInstance();
imageLoader.loadImage(imageUri, imageview);
// Load image, decode it to Bitmap and return Bitmap to callback
imageLoader.loadImage(imageUri,newSimpleImageLoadingListener(){@OverridepublicvoidonLoadingComplete(String imageUri, View view, Bitmap loadedImage){// Do whatever you want with Bitmap}});
// Load image, decode it to Bitmap and return Bitmap synchronously
Bitmap bmp = imageLoader.loadImageSync(imageUri);
完全使用
// Load image, decode it to Bitmap and display Bitmap in ImageView (or any other view // which implements ImageAware interface)
imageLoader.displayImage(imageUri, imageView, options,newImageLoadingListener(){@OverridepublicvoidonLoadingStarted(String imageUri, View view){...}@OverridepublicvoidonLoadingFailed(String imageUri, View view, FailReason failReason){...}@OverridepublicvoidonLoadingComplete(String imageUri, View view, Bitmap loadedImage){...}@OverridepublicvoidonLoadingCancelled(String imageUri, View view){...}},newImageLoadingProgressListener(){@OverridepublicvoidonProgressUpdate(String imageUri, View view,int current,int total){...}});// Load image, decode it to Bitmap and return Bitmap to callback
ImageSize targetSize =newImageSize(80,50);// result Bitmap will be fit to this size
imageLoader.loadImage(imageUri, targetSize, options,newSimpleImageLoadingListener(){@OverridepublicvoidonLoadingComplete(String imageUri, View view, Bitmap loadedImage){// Do whatever you want with Bitmap}});
// Load image, decode it to Bitmap and return Bitmap synchronously
ImageSize targetSize =newImageSize(80,50);// result Bitmap will be fit to this size
Bitmap bmp = imageLoader.loadImageSync(imageUri, targetSize, options);
Load & Display Task Flow
重要, 这个是AUIL的加载图片流程
用户须知
Caching is NOT enabled by default如果需要开启内存或者是磁盘缓存,需要配置DisplayImageOptions
// Create default options which will be used for every // displayImage(...) call if no options will be passed to this method
DisplayImageOptions defaultOptions =newDisplayImageOptions.Builder()....cacheInMemory(true).cacheOnDisk(true)....build();
ImageLoaderConfiguration config =newImageLoaderConfiguration.Builder(getApplicationContext())....defaultDisplayImageOptions(defaultOptions)....build();
ImageLoader.getInstance().init(config);// Do it on Application start
// Then later, when you want to display image
ImageLoader.getInstance().displayImage(imageUrl, imageView); // Default options will be used
或者这样:
DisplayImageOptions options = new DisplayImageOptions.Builder()
...
.cacheInMemory(true)
.cacheOnDisk(true)
...
.build();
ImageLoader.getInstance().displayImage(imageUrl, imageView, options); // Incoming options will be used
为了是ListView or GrideView的性能提升, 使用PauseOnScrollListener
boolean pauseOnScroll =false;// or trueboolean pauseOnFling =true;// or false
PauseOnScrollListener listener =newPauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling);
listView.setOnScrollListener(listener);
If you see in logs some strange supplement at the end of image URL (e.g. http://anysite.com/images/image.png_230x460) then it doesn’t mean this URL is used in requests. This is just “URL + target size”, also this is key for Bitmap in memory cache. This postfix (_230x460) is NOT used in requests.
# 这里使用的是bsdiff patch的JNI库例子.
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
# 设置CMake编译器的版本
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
# 声明源文件路径
file(GLOB bzip "src/main/jni/bzip2/*.c")
file(GLOB bs_src "src/main/jni/*.c")
# 引入头文件路径 (这里必须要引入)
include_directories(
"src/main/jni/bzip2/"
)
# 引入源文件
add_library( # Sets the name of the library.
# 设置编译后的库名称
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
# 设置源文件的位置
${bzip}
src/main/jni/native-lib.c )
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
# 引入依赖库
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
classCarimplementsGroovyInterceptable{defcheck(){
System.out.println("check called ...")}defstart(){
System.out.println("start called ...")}defdrive(){
System.out.println "drive called"}definvokeMethod(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 =newCar()
car.start()
car.drive()
car.check()try{
car.speed()}catch(e){
println e
}
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()
def factorial =[2,3,4,5].inject(1){
previous, element ->
previous * element
}
println factorial
//=====def list =[2,3,4,5]
factorial = list.inject(1){
prviouse, element ->
prviouse * element
}
println factorial
//=====def list =[2,3,4,5]def closure ={
previous, element ->
previous * element
}def factorial = list.inject(1,closure)
println factorial
闭包的其他特性
由于闭包也是一个对象,因此它可以作为方法的参数,同时也可以作为另一个闭包的参数。
作为方法的参数
deffilter(list, predict){return list.findAll(predict)}def isEven ={
x ->return x %2==0}def isOdd ={
x ->return!isEven(x)}def table =[11,12,13,14]def evens =filter(table,isEven)
println evens
def odds =filter(table,isOdd)
println odds
作为另一个闭包的参数
def takewhile ={
predicate, list ->def result =[]for(element in list){if(predicate(element)){
result << element
}else{return result
}}}def isEven ={
x ->return x %2==0}def isOdd ={
x ->return!isEven(x)}def table1 =[12,14,15,18]def table2 =[11,13,15,16,18]def evens = takewhile.call(isEven,table1)
println evens
作为返回值
defmultiply(x){return{
y->return x * y
}}def twice =multiply(2)
println twice(4)
嵌套闭包
选择排序算法的实现
def selection ={
list ->//交换两个位置的数def swap ={
sList, p, q ->def temp = sList[p]
sList[p]= sList[q]
sList[q]= temp
}//找出最小数位置def minimumPosition ={
pList, from ->def mPos = from
def nextFrom =1+ from
for(j in nextFrom..<pList.size){if(pList[j]< pList[mPos]){
mPos = j
}}return mPos
}def size = list.size()-1for(k in0..<size){def minPos =minimumPosition(list, k)swap(list, minPos, k)}return list
}def table =[13,14,12,11,14]def sorted =selection(table)
println sorted
def factorial ={
n ->return n ==0?1: n *call(n -1)}
println factorial(5)
状态类型
可以使用参数和返回值的动态类型来定义闭包。这个特性使得闭包更加通用。
闭包的动态类型
def times ={
x, y ->return x * y
}def times ={
x, y ->return x * y
}
println times(3,4)
println times(3.2,4.15)
println times('hello',4)
在调用时,才确定x和y的类型
12
13.280
hellohellohellohello
静态指定参数类型的闭包
def times ={
Number x, Number y ->return x * y
}
加法和惩罚被称为可交换操作。这意味着A+B = B+A and A*B = B*A。但是减法和除法是不可交换的操作。我们可以事件类似于multiply的闭包。
范例:实现可交换操作
def rSubtract ={
y, x ->return x - y
}def lSubtract ={
x, y ->return x - y
}def subtract10 = rSubtract.curry(10)def subractFrom20 = lSubtract.curry(20)
println subtract10(22)
println subractFrom20(14)
//map closuredef map ={
clos, list ->return list.collect(clos)}//composition closuredef compositon ={
f, g, x ->returnf(g(x))}def multiply ={
x, y ->return x * y
}def triple = multiply.curry(3)def quadroup = multiply.curry(4)def composeMapMap = compositon.curry(map.curry(triple), map.curry(quadroup))def table =composeMapMap([1,2,3,4])// each element * 4 * 3
println table
业务规则
现在我们考虑如何计算一个Book的净价,在计算过程要考虑到上品折扣和政府税金,比如增值税。
关于业务规则的实际实现
范例:净价计算
classBook{def name
def author
def price
def category
}def bk =newBook(name:'Groovy', author:'KenB', price:25, category:'CompSci')// 参数列表初始化def discountRate =0.1def taxRate =0.17def rMultiply ={
y , x ->return x * y
}def lMultiply ={
x , y ->return x * y
}def composition ={
f,g,x ->returnf(g(x))}def calDiscounteedPrice = rMultiply.curry(1-discountRate)def calTax = rMultiply.curry(1+ taxRate)def calcNetPrice = composition.curry(calTax,calDiscounteedPrice)def netPrice =calcNetPrice(bk.price)
println "netPrice = ${netPrice}"
范例:有上限折扣
classBook{def name
def author
def price
def category
}def bk =newBook(name:'Groovy', author:'KenB', price:25, category:'CompSci')def discountRate =0.1def taxRate =0.17def maxDiscount =3def rMultiply ={
y, x ->return x * y
}def lMultiply ={
x, y ->return x * y
}def subtract ={
x, y ->return x - y
}def rSubtract ={
y, x ->return x - y
}def lSubtract ={
x, y ->return x - y
}def min ={
x, y ->return x < y ? x : y
}def id ={
x ->return x
}def composition ={
f, g, x ->returnf(g(x))}def bComposition ={
h, f, g, x ->returnh(f(x),g(x))}def calcDiscount = rMultiply.curry(discountRate)def calcActuralDiscount = bComposition.curry(min, calcDiscount, id)def calcDiscountedPrice = bComposition.curry(subtract, id, calcActuralDiscount)def calcTax = rMultiply.curry(1+ taxRate)def calcNetPrice = composition.curry(calcTax,calcDiscountedPrice)
println "bk.price : $bk.price"def netPrice =calcNetPrice(bk.price)
println "netprice = $netPrice"
abstract class Functor {
public static Closure bAdd = {
x, y -> return x + y
}
public static Closure rAdd = {
y, x -> return x + y
}
public static Closure bSubtract = {
x , y -> return x - y
}
//blabla
}
在Java中,wait() and notify()与多线程借个使用,可以实现协程.闭包会让人产生”协程是在一个线程中执行”的感觉or错觉.
defiterate(n, closure){1.upto(n){
println "In iterate with value ${it}"closure(it)}}
println "Calling iterate"
total =0iterate(4){
total += it
println "In closure total so far is ${total}"}
println "Done"/**
每次调用闭包,我们都会从上一次调用中回复total的值. //可是我并没有从例子中看出什么是协程????
*/