图片 1

Android 最火的快速开发框架XUtils

整个框架式不同于androidannotations,Roboguice等ioc框架,这是一个类似spring的实现方式。在整应用的生命周期中找到切入点,然后对activity的生命周期进行拦截,然后插入自己的功能。

Github下载地址:

图片 1

Android
最火框架XUtils之注解机制详解

框架的说明

如果你想看ui方面的东西,这里没有,想要看牛逼的效果这里也没有。这只是纯实现功能的框架,它的目标是节省代码量,降低耦合,让代码层次看起来更清晰。整个框架一部分是网上的,一部分是我改的,为了适应我的编码习惯,还有一部分像orm完全是网上的组件。在此感谢那些朋友们。整个框架式的初衷是为了偷懒,之前都是一个功能一个jar,做项目的时候拉进去,这样对于我来说依然还是比较麻烦。最后就导致我把所有的jar做成了一个工具集合包。有很多框架都含有这个工具集合里的功能,这些不一定都好用,因为这是根据我个人使用喜欢来实现的,如果你们有自己的想法,可以自己把架包解压了以后,源码拉出来改动下。目前很多框架都用到了注解,除了androidannotations没有入侵我们应用的代码以外,其他的基本上都有,要么是必须继承框架里面的
activity,要么是必须在activity的oncreat里面调用某个方法。整个框架式不同于androidannotations,Roboguice等ioc框架,这是一个类似spring的实现方式。在整应用的生命周期中找到切入点,然后对activity的生命周期进行拦截,然后插入自己的功能。

如果需要混淆 第一步 你要先引入你得架包 -libraryjars  
libs/android-support-v4.jar -libraryjars   libs/loonandroid.jar 第二步
你要保证注解在代码优化的时候不能被删除掉 -keepattributes Signature
-keepattributes Annotation第三步 support4 要排除掉 -dontwarn
android.support.v4.**
-keep class android.support.v4.** { ; }
-keep interface android.support.v4.app.
* { ; }
-keep public class
extends android.support.v4.
-keep public class * extends android.app.Fragment 第四步
只要使用了注解的包名 全部排除掉 -dontwarn xxx.**
-keep class xxx.** { ; }
其中XXX替换成你使用了注解的包名第五步 保证R不被混淆 -keep class **.R$

{
*;
} 即OK

xUtils简介

框架的主要功能

其中分为以下几种:

  • 自动注入框架(只需要继承框架内的application既可)
  • 图片加载框架(多重缓存,自动回收,最大限度保证内存的安全性)
  • 网络请求模块(继承了基本上现在所有的http请求)
  • eventbus(集成一个开源的框架)
  • 验证框架(集成开源框架)
  • json解析(支持解析成集合或者对象)
  • 数据库(不知道是哪位写的 忘记了)
  • 多线程断点下载(自动判断是否支持多线程,判断是否是重定向)
  • 自动更新模块
  • 一系列工具类

xUtils 包含了很多实用的android工具。

一 自动注入框架

xUtils
最初源于Afinal框架,进行了大量重构,使得xUtils支持大文件上传,更全面的http请求协议支持(10种谓词),拥有更加灵活的ORM,更多的事件注解支持且不受混淆影响…

1 无需继承任何BaseActivity

举例:普通activity

    public class FourActivity extends Activity {

        View xx;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main4);
            xx = find......;
            //---------------------------------------------------------
            组件的初始化
            //---------------------------------------------------------
        }
    }

这其中我们会耗费大量的代码或者重复性的去些一些代码。特别是布局比较复杂的情况下。

如果用框架

    @InjectLayer(R.layout.activity_main3)
    public class ThirdActivity extends Activity {
        @InjectView
        View xx;
    }

即可

像软件的说明页面,就是单纯的展示一个布局,那么就是

    @InjectLayer(R.layout.activity_main3)
    public class ThirdActivity extends Activity {
    }

即可

整个ioc框架不需要你继承任何的acitivity,这样就保证了不会在你的代码结构层次上造成影响,因为有的时候你需要自己的BaseActivity来实现你公用的功能。

xUitls最低兼容android 2.2 (api level 8)

2 支持子父布局

这种情况下,对于一般的框架来说,做法有以下几种:

  • ActivityGroup
     一般的ioc框架都需要继承框架内的activity,activitygroup会让很多框架用不了,现在ActivityGroup也是不提倡的了。
  • BaseActivity 一般的Ioc框架会需要你的BaseActivity
    去继承框架内的activity
  • 中间用fragment
    这样的情况也一样,你的FragmentActivity必须继承它的activity才能实现ioc框架功能。对于这个框架来说很容易实现

1 ActivityGroup  你不需要继承任何activity 和普通activity
实现方式(如上面的例子)

2 BaseActivity

见代码:

首先是BaseActivity        @InjectPLayer(R.layout.activity_com)      
 public class BaseActivity extends Activity {}

其中R.layout.activity_com是包括上下导航的布局,中间是一个view子activity只需要这么写即可

    @InjectLayer(value = R.layout.activity_main, parent = R.id.common)
    public class MainActivity extends BaseActivity {}

当然
又会有问题了,那么我上下导航里面的点击事件怎么绑定,怎么去初始化,难道要每一个子activity都要去写吗?当然不需要

    @InjectPLayer(R.layout.activity_com)
    public class BaseActivity extends Activity {
    @InjectInit
    private void init() {
        MeApplication.logger.s("公共类的初始化");
    }

    // 这里是第一种交互事件注入方式(单击)
    @InjectMethod(@InjectListener(ids = { R.id.top, R.id.bottom }, listeners = { OnClick.class }))
    private void click2(View view) {
        Handler_TextStyle handler_TextStyle = new Handler_TextStyle();
        switch (view.getId()) {
            case R.id.top:
                handler_TextStyle.setString("点击了顶部按钮(在基类中统一注册,也可以单独注册)");
                handler_TextStyle.setBackgroundColor(Color.RED, 3, 5);
                Toast.makeText(this, handler_TextStyle.getSpannableString(), Toast.LENGTH_LONG).show();
                break;
            case R.id.bottom:
                handler_TextStyle.setString("点击了底部按钮(在基类中统一注册,也可以单独注册)");
                handler_TextStyle.setBackgroundColor(Color.RED, 3, 5);
                Toast.makeText(this, handler_TextStyle.getSpannableString(), Toast.LENGTH_LONG).show();
            break;
            }
        }
    }

如上 其中@InjectInit注解表示不管是在子activity还是父activity
都是在布局初始化完成以后才会调用,其先后顺序是

    父布局layout->子布局layout->父布局ioc和事件绑定->子布局事件绑定。

父activity
中可以对所有的公用组件和事件进行初始化和绑定还没完,又会有另一个问题,如果我某个页面下导航的a按钮和其他页面底部a按钮的功能不一样
要单独设置怎么办。那么我们可以在子布局进行@InjectMethod和@InjectView进行事件绑定和组件注入,它们会覆盖父类中相同id的组件的操作以下是view注入的方法说明:

目前xUtils主要有四大模块:

@InjectPLayer

表示是Activity的setContentView

    @InjectLayer(value = R.layout.activity_main2, parent = R.id.common, isFull = true, isTitle = true)

其中需要哪个参数就用哪个,value 是必须的
如果只有layout可以这么写@InjectPLayer(R.layout.activity_com)。其中value
表示layout,parent表示它在父布局中所对应组件的id 如上图中
中间显示区域的view的id。Isfull是否全屏,默认为false.isTitle
是否有标题,默认false;

DbUtils模块:

@InjectView

自动注入view注解。

android中的orm框架,一行代码就可以进行增删改查;

支持事务,默认关闭;

可通过注解自定义表名,列名,外键,唯一性约束,NOT
NULL约束,CHECK约束等(需要混淆的时候请注解表名和列名);

支持绑定外键,保存实体时外键关联实体自动保存或更新;

自动加载外键关联实体,支持延时加载;

支持链式表达查询,更直观的查询语义,参考下面的介绍或sample中的例子。

基本写法:

    @InjectView
    TextView test;

其中test表示它在xml中对应的Id为test

    @InjectView(R.id.next2)
    TextView test;

表示它在xml中对应的Id为next2

ViewUtils模块:

高级写法:

    @InjectView(binders = { @InjectBinder(method = "click", listeners = { OnClick.class, OnLongClick.class }) })
    Button next, next3, next4;

其中表示对id为next,next3,next4进行注解,其中binders
表示绑定了以下事件,binders
是个数组,也就是说可以用多个InjectBinder绑定多个事件,也可以用listeners
= { OnClick.class, OnLongClick.class
}来表示对组件注入了点击事件和长按事件

    @InjectView(value = R.id.next2, binders = { @InjectBinder(method = "click", listeners = { OnClick.class }) })
    Button button;

对于变量名和组件id不一致的view则需要设置value Click
表示那些注入的事件触发以后所调用的方法,其必须在当前类内。 //
支持由参数和无参数 即click(View view)或者click()
当然click名字必须对于变量注解中的method = “click”

    private void click(View view) {
        switch (view.getId()) {
            case R.id.next:
            startActivity(new Intent(this, ThirdActivity.class));
            break;
            ...
        }
    }

android中的ioc框架,完全注解方式就可以进行UI,资源和事件绑定;

新的事件绑定方式,使用混淆工具混淆后仍可正常工作;

目前支持常用的20种事件绑定,参见ViewCommonEventListener类和包com.lidroid.xutils.view.annotation.event。

@InjectResource

    @InjectResource
    String action_settings;

    @InjectResource
    Drawable ic_launcher;

InjectResource支持string和drawable的注解

HttpUtils模块:

@InjectMethod

// 底部导航栏 子类覆盖父类

    @InjectMethod(@InjectListener(ids = { R.id.bottom }, listeners = { OnClick.class, OnLongClick.class }))
    private void click3(View view) {
        Handler_TextStyle handler_TextStyle = new Handler_TextStyle();
        handler_TextStyle.setString("点击了底部按钮 子类覆盖了父类");
        handler_TextStyle.setBackgroundColor(Color.RED, 3, 5);
        Toast.makeText(this, handler_TextStyle.getSpannableString(), Toast.LENGTH_LONG).show();
    }

@InjectMethod是当我们对一个组件只需要触发而不需要find出来的时候用到。
ids 表示绑定哪些id,listeners 表示绑定哪些事件 这两个参数都是数组

当然 如果嫌注解字段太长,可以自己修改。这个是整个view的注入。

支持同步,异步方式的请求;

支持大文件上传,上传大文件不会oom;

支持GET,POST,PUT,MOVE,COPY,DELETE,HEAD,OPTIONS,TRACE,CONNECT请求;

下载支持301/302重定向,支持设置是否根据Content-Disposition重命名下载的文件;

返回文本内容的请求(默认只启用了GET请求)支持缓存,可设置默认过期时间和针对当前请求的过期时间。

@InjectInit

    @InjectInit
    void init() {
        MeApplication.logger.s("子类的初始化");
        test.setText("初始化完成,第一个页面");
    }

这个注解你在activity中添加到任何一个方法名上,那么,当所有的layout和所有的view以及事件绑定完毕以后,会第一个调用含有这个注解的方法。它相当于oncreat

    注意:框架注解了整个activity的生命周期, @InjectOnNewIntent,@InjectPause,@InjectResume,
    @InjectRestart,@InjectStart,@InjectStop 其中OnDestroy无注解。
    如果Activity中有含有这些注解的方法 那么不同生命周期下回自动调用这些方法

BitmapUtils模块:

二:Fragment的自动注入

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        this.inflater = inflater;
        View rootView = inflater.inflate(R.layout.activity_left, container, false);
        Handler_Inject.injectView(this, rootView);
        return rootView;
    }

    只需要在onCreateView里面调用Handler_Inject.injectView(this, rootView);
    即可

    在fragment中除了activity的生命周期注解和@InjectLayer注解无法使用外,组件绑定和事件绑定都可以使用,@InjectBefore也可以使用

    @InjectBefore 是在组件初始化之前调用

加载bitmap的时候无需考虑bitmap加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象;

支持加载网络图片和本地图片;

内存管理使用lru算法,更好的管理bitmap内存;

可配置线程加载线程数量,缓存大小,缓存路径,加载显示动画等…

三:图片下载框架

    这个是图片框架重写了好多次了,总是有点问题,里面基本上每一段代码都有注释,还有一些bug,
    因为项目中用的还是这次重写之前的。
    如果大家发现问题,记得告诉我框架中调用的方法名和参数基本上都不会变,避免替换jar导致需要改动大部分代码。

整个图片下载的逻辑是这样的:

  • 1 根据url和view去调用图片下载的方法
  • 2 从缓存去拿bitmap
  • 3 如果bitmap不为空 判断是否针对这个url有单独的配置
    没有则使用全局配置加载图片
  • 4 如果bitmap为空 则开启线程,放到本地线程池中,然后从本地文件读取
  • 5 如果文件存在,则转为bitmap放到缓存,然后重复2,然后9
  • 6 如果文件不存在,则开启线程放到网络线程池中去下载文件
  • 7 下载成功则放到本地sdcard
    然后把文件转为bitmap放到缓存,然后重复2,然后9
  • 8 下载不成功,然后重复2,然后9
  • 9 如果bitmap不为空 判断是否针对这个url有单独的配置
    没有则使用全局配置加载这张图片 如果bitmap为空 则显示失败的默认图

具体的流程 可以参考源码

使用xUtils快速开发框架需要有以下权限:

缓存分为三层

    第一层是LruCache(原理去百度)
    第二层是LinkedHashMap
    第三层是 view标记

    1 当LruCache中的图片超过了规定了内存,那么从LruCache移除一个使用最少的,放到LinkedHashMap中
    2 当每一张图片的url对应一个count,一旦加载一张图片,那么这个url的count加1
    3 自定义AsyImageView继承ImageView,重写了onDetachedFromWindow方法,一旦
        AsyImageView从当前视图移除掉会调用onDetachedFromWindow该方法,此刻该图片所对应的url数目count减1
    4 因为listview中的imageview如果用了ViewHolder那么第3条就不适合了,此刻每一个imagview的hashCode对应一个url,
        一旦imagview更换了一个新的url,那么该imagview的hashcode上一个的引用将被移除,
        那么上一次显示的url所对应的count将减1
    5 当LinkedHashMap超过了规定限制的时候,那么遍历所有的count一旦count为0 则移除回收

<uses-permissionandroid:name=”android.permission.INTERNET”/>

<uses-permissionandroid:name=”android.permission.WRITE_EXTERNAL_STORAGE”/>

图片下载使用

一:必须条件

    必须在配置文件中添加配置,来打开图片下载引擎的初始化,为了减少启动时间,默认关闭。
    #开启框架内置的图片下载 如果不设置 则无法使用框架类的图片下载
    imageload_open=true

    二:使用方法

混淆时注意事项:

1 普通图片下载

    ImageDownloader.download("网络和本地图片链接",mAsyImageView);

如果需要配置bitmap的高宽

第一种方式:

    在xml布局文件中对AsyImageView的高宽进行设置

第二种方式:

全局图片配置,所有图片显示默认用此配置

    GlobalConfig globalConfig = GlobalConfig.getInstance();
    globalConfig.setMaxWidth(w);

来设置

第三种

    SingleConfig config = new SingleConfig();
    config ....设置宽高
    ImageDownloader.download("网络和本地图片链接",mAsyImageView,config )

其中优先级

添加Android默认混淆配置${sdk.dir}/tools/proguard/proguard-android.txt

不要混淆xUtils中的注解类型,添加混淆配置:-keep class * extends
java.lang.annotation.Annotation { *; }

对使用DbUtils模块持久化的实体类不要混淆,或者注解所有表和列名称@Table(name=”xxx”),@Id(column=”xxx”),@Column(column=”xxx”),@Foreign(column=”xxx”,foreign=”xxx”);

第三种 > 第一种 > 第二种

        其中GlobalConfig  支持的设置有高宽的设置,内存缓存的大小,默认图片,
        下载失败的图片,最大缓存数目,线程池,缓存类型,显示控制,listview得滑动监听,图片加载动画
        其中SingleConfig 支持的设置有高宽的设置,默认图片,下载失败的图片,下载进度,显示控制,加载动画

其中SingleConfig 优先于GlobalConfig

DbUtils使用方法:

支持配置文件配置:

    mAsyImageView.setTemplate("one");
    ImageDownloader.download("url",mAsyImageView);

其中one在配置文件里面配置,这样
不管在任何地方,只要AsyImageView.setTemplate(“one”);就可以使用名称为one的配置了。

支持本地文件加载调用接口不变。

需要进度显示的:

    SingleConfig config = new SingleConfig();
    config.setDisplayer(new DisplayerLister() {
        @Override
        public void startLoader(AsyImageView imageView) {
            super.startLoader(imageView);
        }
        @Override
        public Bitmap finishLoader(Bitmap bitmap, AsyImageView imageView) {
            pin_progress_1.setVisibility(View.GONE);
            return bitmap;
        }

        @Override
        public void progressLoader(int progress, AsyImageView imageView) {
            pin_progress_1.setProgress(progress);
            super.progressLoader(progress, imageView);
        }
    });
    ImageDownloader.download("url",photo,config);

其中url的服务器必须支持获取文件长度

需要显示动画的:如果是单独某一个图片

    SingleConfig config = new SingleConfig();
    config.setDisplayerAnimation(new FadeInAnimation());

如果是全局的

    GlobalConfig config = new GlobalConfig();
    config.setDisplayerAnimation(new FadeInAnimation());

其中FadeInAnimation是框架自带的一个渐变的动画如果需要自定义
实现DisplayerAnimation接口即可

DbUtils db=DbUtils.create(this);

User
user=newUser();//这里需要注意的是User对象必须有id属性,或者有通过@ID注解的属性

user.setEmail(“wyouflf@qq.com”);

user.setName(“wyouflf”);db.save(user);//
使用saveBindingId保存实体时会为实体的id赋值

…// 查找Parententity=db.findById(Parent.class,parent.getId());

List list=db.findAll(Parent.class);//通过类型查找Parent
Parent=db.findFirst(Selector.from(Parent.class).where(“name”,”=”,”test”));

// IS NULL

Parent
Parent=db.findFirst(Selector.from(Parent.class).where(“name”,”=”,null));

// IS NOT NULL

Parent
Parent=db.findFirst(Selector.from(Parent.class).where(“name”,”!=”,null));

// WHERE id<54 AND (age>20 OR age<30) ORDER BY id LIMIT
pageSize OFFSET pageOffset

List
list=db.findAll(Selector.from(Parent.class).where(“id”,”<“,54).and(WhereBuilder.b(“age”,”>”,20).or(“age”,”
<
“,30)).orderBy(“id”).limit(pageSize).offset(pageSize*pageIndex));

// op为”in”时,最后一个参数必须是数组或Iterable的实现类(例如List等)

Parenttest=db.findFirst(Selector.from(Parent.class).where(“id”,”in”,newint[]{1,2,3}));

//
op为”between”时,最后一个参数必须是数组或Iterable的实现类(例如List等)

Parenttest=db.findFirst(Selector.from(Parent.class).where(“id”,”between”,newString[]{“1″,”5”}));

DbModeldbModel=db.findDbModelAll(Selector.from(Parent.class).select(“name”));

//select(“name”)只取出name列ListdbModels=db.findDbModelAll(Selector.from(Parent.class).groupBy(“name”).select(“name”,”count(name)”));

ListdbModels=db.findDbModelAll(sql);//
自定义sql查询db.execNonQuery(sql)

// 执行自定义sql…

2 listview中图片下载

    只要在listview的注解@InjectView(isasy=true)中添加了isasy=true(默认为false)
    那么系统会自动给你注入OnScrollListener滚动事件,以便实现图片飞行停止才加载,缓慢拖动加载的功能。如果你要实现自己的OnScrollListener

如下

    @InjectBefore
    void test(){
        //@InjectView(isasy=true)表示这个listview里面有网络图片下载,并且需要实现滑动停止才加载的功能
        //@InjectView(isasy=true)框架会给listview自动注入OnScrollListener,如果你自己也要滚动监听
        //那么请在此配置,如下
        GlobalConfig config = GlobalConfig.getInstance();
        config.setOnScrollLoaderListener(new MyOnScrollListener());
        System.out.println("before");
    }
    //必须继承框架内的滚动监听
    class MyOnScrollListener extends OnScrollLoaderListener{
    @Override
    public void onScrollListener(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        ApplicationBean.logger.s("滚动监听:"+firstVisibleItem);
    }

    @Override
    public void onScrollStateChange(AbsListView view, int scrollState) {
        ApplicationBean.logger.s("滚动状态");
        }
    }

@InjectBefore
表示在组件初始化以前开始调用,因为滚动监听必须在listview被初始化之前赋值,否则无效
将默认使用框架内的滚动监听

ViewUtils使用方法

3 无需显示的图片下载

    ImageDownloader.download("url", new LoaderLister() {
        @Override
        public void finishLoader(String url, File file) {
            System.out.println("下载完成"+file.getPath());
        }
        @Override
        public void failLoader(String url) {
            System.out.println("下载失败");
        }
    });

如果需要下载进度

    ImageDownloader.download("url", new LoaderLister() {

        @Override
        public void startLoader(String url) {
            System.out.println("开始下载");
            super.startLoader(url);
        }

        @Override
        public void finishLoader(String url, File file) {
            System.out.println("下载完成"+file.getPath());
        }

        @Override
        public void progressLoader(int progress) {
            System.out.println("下载进度"+progress);
            super.progressLoader(progress);
        }
    });

完全注解方式就可以进行UI绑定和事件绑定。

无需findViewById和setClickListener等。

//
xUtils的view注解要求必须提供id,以使代码混淆不受影响。@ViewInject(R.id.textView)TextViewtextView;

//@ViewInject(vale=R.id.textView, parentId=R.id.parentView)

//TextView textView;

@ResInject(id=R.string.label,type=ResType.String)privateStringlabel;/

/ 取消了之前使用方法名绑定事件的方式,使用id绑定不受混淆影响

// 支持绑定多个id @OnClick({R.id.id1, R.id.id2, R.id.id3})

// or @OnClick(value={R.id.id1, R.id.id2, R.id.id3},
parentId={R.id.pid1, R.id.pid2, R.id.pid3})

//
更多事件支持参见ViewCommonEventListener类和包com.lidroid.xutils.view.annotation.event。@OnClick(R.id.test_button)publicvoidtestButtonClick(Viewv){

//
方法签名必须和接口中的要求一致…}…//在Activity中注入:@OverridepublicvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.main);ViewUtils.inject(this);

//注入view和事件

textView.setText(“some text…”);…}

//在Fragment中注入:@OverridepublicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,BundlesavedInstanceState){

Viewview=inflater.inflate(R.layout.bitmap_fragment,container,false);

// 加载fragment布局

ViewUtils.inject(this,view);

//注入view和事件

…}

//在PreferenceFragment中注入:publicvoidonActivityCreated(BundlesavedInstanceState){

super.onActivityCreated(savedInstanceState);

ViewUtils.inject(this,getPreferenceScreen());

//注入view和事件.

..}

// 其他重载

// inject(View view);

// inject(Activity activity)

// inject(PreferenceActivity preferenceActivity)

// inject(Object handler, View view)

// inject(Object handler, Activity activity)

// inject(Object handler, PreferenceGroup preferenceGroup)

// inject(Object handler, PreferenceActivity preferenceActivity)

HttpUtils使用方法:

普通get方法

HttpUtilshttp=newHttpUtils();

http.send(HttpRequest.HttpMethod.GET,”

@Override

public void onLoading(longtotal,longcurrent,booleanisUploading){

testTextView.setText(current+”/”+total);

}

@Override

public void onSuccess(ResponseInforesponseInfo){

textView.setText(responseInfo.result);

}

@Override

public void onStart(){}

@Override

public void onFailure(HttpExceptionerror,Stringmsg){}

});

使用HttpUtils上传文件 或者
提交数据 到服务器(post方法)

RequestParamsparams=newRequestParams();

params.addHeader(“name”,”value”);

params.addQueryStringParameter(“name”,”value”);

// 只包含字符串参数时默认使用BodyParamsEntity,

//
类似于UrlEncodedFormEntity(”application/x-www-form-urlencoded”)。params.addBodyParameter(“name”,”value”);

// 加入文件参数后默认使用MultipartEntity(”multipart/form-data”),

//
如需”multipart/related”,xUtils中提供的MultipartEntity支持设置subType为”related”。

//
使用params.setBodyEntity(httpEntity)可设置更多类型的HttpEntity(如:

//
MultipartEntity,BodyParamsEntity,FileUploadEntity,InputStreamUploadEntity,StringEntity)。

// 例如发送json参数:params.setBodyEntity(new
StringEntity(jsonStr,charset));

params.addBodyParameter(“file”,newFile(“path”));

HttpUtilshttp=newHttpUtils();

http.send(HttpRequest.HttpMethod.POST,”uploadUrl….”,params,newRequestCallBack(){

@Override

public void onStart(){testTextView.setText(“conn…”);}

@Override

public void onLoading(longtotal,longcurrent,booleanisUploading){

if(isUploading){

testTextView.setText(“upload: “+current+”/”+total);

}else{

testTextView.setText(“reply: “+current+”/”+total);}

}

@Override

public void onSuccess(ResponseInforesponseInfo){

testTextView.setText(“reply: “+responseInfo.result);

}

@Override

public void onFailure(HttpExceptionerror,Stringmsg){

testTextView.setText(error.getExceptionCode()+”:”+msg);}

});

使用HttpUtils下载文件:

支持断点续传,随时停止下载任务,开始任务

HttpUtilshttp=newHttpUtils();

HttpHandlerhandler=http.download(“,

//
如果目标文件存在,接着未完成的部分继续下载。服务器不支持RANGE时将从新下载。true,

//
如果从请求返回信息中获取到文件名,下载完成后自动重命名。newRequestCallBack(){

@Override

public void onStart(){

testTextView.setText(“conn…”);

}

@Override

public void onLoading(longtotal,longcurrent,booleanisUploading){

testTextView.setText(current+”/”+total);}@OverridepublicvoidonSuccess(ResponseInforesponseInfo){testTextView.setText(“downloaded:”+responseInfo.result.getPath());

}

@Override

public void onFailure(HttpExceptionerror,Stringmsg){

testTextView.setText(msg);}

});

…//调用cancel()方法停止下载

handler.cancel();

BitmapUtils
使用方法

BitmapUtils bitmapUtils=newBitmapUtils(this);

//
加载网络图片bitmapUtils.display(testImageView,””);

// 加载本地图片(路径以/开头, 绝对路径)

bitmapUtils.display(testImageView,”/sdcard/test.jpg”);

// 加载assets中的图片(路径以assets开头)

bitmapUtils.display(testImageView,”assets/img/wallpaper.jpg”);

//
使用ListView等容器展示图片时可通过PauseOnScrollListener控制滑动和快速滑动过程中时候暂停加载图片listView.setOnScrollListener(newPauseOnScrollListener(bitmapUtils,false,true));

listView.setOnScrollListener(newPauseOnScrollListener(bitmapUtils,false,true,customListener));

输出日志
LogUtils

// 自动添加TAG,格式: className.methodName(L:lineNumber)//
可设置全局的LogUtils.allowD = false,LogUtils.allowI =
false…,控制是否输出log。// 自定义log输出LogUtils.customLogger = new
xxxLogger();LogUtils.d(“wyouflf”);

转载:

发表评论

电子邮件地址不会被公开。 必填项已用*标注