谷歌电子市场开发流程(6)-xutils的使用

来源:互联网 发布:淘宝卖家怎么激活 编辑:程序博客网 时间:2024/05/29 11:17
昨天没有更新博客,因为调bug调了太长时间,因为封装的问题,逻辑显得很复杂,跟着断点调了很多次,最后才找到问题,顿时觉得身心俱疲,博客也就没有心思去更新了,好了,牢骚发完了,那就赶紧开始吧。。。
昨天将网络架构基本上搭建完了,一旦框架搭好,后面的填充数据就会显得异常容易。个人认为呢,android主要是以显示数据为主的,怎样将具体的数据,转换为用户看的懂得图像,文字,是最重要的,当然,美观也占了举足轻重的地位,在开发过程中呢,我们经常会遇到加载从网络上获取到的图片,在今天之前,这个问题还一直困扰着我,我一直觉得这会是一件非常复杂的事。
我们都知道,承载图片的控件有很多,专门显示图片的当然也就是ImageView了,由于这个控件本身的属性,在其上显示的图片你需要有图片资源好,但是,从网络上请求数据呢,往往传过来的,都只是一个URL,告诉你从哪个地方加载就够了,这个就比较烦了,因为,你不可能在ImageView里面显示一个网址吧,,那么,有没有方法,只需要URL,然后直接将加载的图片放进ImageView呢。
答案就是使用Xutils框架,这是一个很庞大的框架包,里面包含很多东西,我们想用的时候,可以直接去调就可以了,在网上查了查,关于这个的文章也很多,本人菜鸟一枚,当然解释的不会像网上大神那么详尽,我写博客的目的,本身也就是给我自己记录,加深对知识点的印象,防止以后忘记又不知从何处找答案。
说一说我对这些的理解啊(可能会有很多理解错误的地方,欢迎批评指正)
xutils呢,主要分为四大模块,有对数据库操作方面进行优化的DbUtils,对UI控件进行优化的ViewUtils,对网络请求进行优化的HttpUtils,对Bitmap加载图片进行优化的BitmapUtils,我现在使用过的也就是ViewUtils,HttpUtils和BitmapUtils,DbUtils还没有使用过,不过想想如果用了的话会节省不少事,因为,数据库的操作实在是很多,增删改查有很多代码都很类似,如果不使用工具,实在是很烦。ViewUtils中,我只用过注解,个人感觉啊,很鸡肋,当然可能是我现在开发经验不足,没有遇到使用注解使用的很爽的情境,我理解中的注解呢,就是,你用了这个工具之后,不用findViewById和set一些事件了,只需要短短一行代码,就可以让你的控件可以在代码中使用,我觉得用起来也就那样吧。
比如说,你在xml文件中,敲了一个id为text_name的TextView控件,如果你要在代码中使用它,平常的方法就是通过TextView text_name=(TextView)findViewById(R.id.text_name);找到它,这里又是声明对象,又是类型转换,但是如果使用了ViewUtils,只需要@ViewInject(R.id.text_name),在方法中ViewUtils.inject(this)注入就可以了。此外,如果你有多个控件需要声明,那么只需要将id一起传过去就好了,@onClick(R.id.a1,R.id.a2,R.id.a3),这样三个控件的点击事件也声明好了,也是很方便。
// xUtils的view注解要求必须提供id,以使代码混淆不受影响。
@ViewInject(R.id.textView)
TextView textView;

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

@ResInject(id= R.string.label,type = ResType.String)
private Stringlabel;

// 取消了之前使用方法名绑定事件的方式,使用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)
public void testButtonClick(Viewv) { // 方法签名必须和接口中的要求一致
    ...
}
...
//在Activity中注入:
@Override
public void onCreate(BundlesavedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    ViewUtils.inject(this);//注入view和事件
    ...
    textView.setText("some text...");
    ...
}
//在Fragment中注入:
@Override
public ViewonCreateView(LayoutInflaterinflater, ViewGroup container,Bundle savedInstanceState){
    View view = inflater.inflate(R.layout.bitmap_fragment,container,false);// 加载fragment布局
    ViewUtils.inject(this,view); //注入view和事件
    ...
}
//在PreferenceFragment中注入:
public void onActivityCreated(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呢,就比较实用了,请求网络其实是一件很烦的事情,要声明很多属性,还得读数据,提交数据,这又得一大堆代码,但是实用HttpUtils之后呢,你只需要先new一个HttpUtils对象,然后调用它的send方法,传三个参数,第一个是你要请求的方式,是get还是post,第二个就是,你要请求的URL,第三个是一个回调接口,你需要实现它的四个方法,onLoading()(请求中),onStart()(开始请求),onSuccess()(请求成功),onFailure()(请求失败),就OK了。
提交数据呢,差不多,但是你得先声明好你要提交数据的参数。
(1)get方法
HttpUtils http = new HttpUtils();
http.send(HttpRequest.HttpMethod.GET,
    "http://www.lidroid.com",
    new RequestCallBack<String>(){
        @Override
        public void onLoading(longtotal, long current,boolean isUploading) {
            testTextView.setText(current+ "/" + total);
        }

        @Override
        public void onSuccess(ResponseInfo<String>responseInfo){
            textView.setText(responseInfo.result);
        }

        @Override
        public void onStart(){
        }

        @Override
        public void onFailure(HttpExceptionerror, String msg){
        }
});
(2)post方法
RequestParams params = new RequestParams();
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",new File("path"));
...

HttpUtils http = new HttpUtils();
http.send(HttpRequest.HttpMethod.POST,
    "uploadUrl....",
    params,
    new RequestCallBack<String>(){

        @Override
        public void onStart(){
            testTextView.setText("conn...");
        }

        @Override
        public void onLoading(longtotal, long current,boolean isUploading) {
            if (isUploading){
                testTextView.setText("upload: "+ current + "/" + total);
            } else {
                testTextView.setText("reply: "+ current + "/" + total);
            }
        }

        @Override
        public void onSuccess(ResponseInfo<String>responseInfo){
            testTextView.setText("reply: "+ responseInfo.result);
        }

        @Override
        public void onFailure(HttpExceptionerror, String msg){
            testTextView.setText(error.getExceptionCode()+ ":" + msg);
        }
});
BitmapUtils我觉得很实用,加载网络图片的应用场景实在是太多了,有了这个工具后,我觉得省了一大波事。先new一个BItmapUtils对象,调用dispaly()方法,传第一个参数就是你要填充数据的控件对象,第二个参数就是,图片的URL
BitmapUtils bitmapUtils = new BitmapUtils(this);

// 加载网络图片
bitmapUtils.display(testImageView,"http://bbs.lidroid.com/static/image/common/logo.png");

// 加载本地图片(路径以/开头, 绝对路径)
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));
这里呢,如果你有多个类都需要使用这个工具,那么不停的new一个BitmapUtils对象,这对象又不会被销毁,就会容易造成内存溢出,所以建议这里用单例模式比较好。

DbUtils理解不深,先存一波代码

DbUtils db = DbUtils.create(this);
User user = new User(); //这里需要注意的是User对象必须有id属性,或者有通过@ID注解的属性
user.setEmail("wyouflf@qq.com");
user.setName("wyouflf");
db.save(user);// 使用saveBindingId保存实体时会为实体的id赋值

...
// 查找
Parent entity = db.findById(Parent.class,parent.getId());
List<Parent>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<Parent>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等)
Parent test = db.findFirst(Selector.from(Parent.class).where("id","in",new int[]{1,2,3}));
// op为"between"时,最后一个参数必须是数组或Iterable的实现类(例如List等)
Parent test = db.findFirst(Selector.from(Parent.class).where("id","between",new String[]{"1","5"}));

DbModel dbModel = db.findDbModelAll(Selector.from(Parent.class).select("name"));//select("name")只取出name列
List<DbModel>dbModels =db.findDbModelAll(Selector.from(Parent.class).groupBy("name").select("name","count(name)"));
...

List<DbModel>dbModels =db.findDbModelAll(sql);// 自定义sql查询
db.execNonQuery(sql)// 执行自定义sql
...