Android项目开发全程(二)--Afinal用法简单介绍
本篇博文接上篇的《Android项目开发全程(一)--创建工程》,主要介绍一下在本项目中用到的一个很重要的框架-Afinal,由于本系列博文重点是项目开发全程,所以在这里就先介绍一下本项目中用到的几个功能:
Afinal简介
- Afinal 是一个android的sqlite orm 和 ioc 框架。同时封装了android中的http框架,使其更加简单易用;
- 使用finalBitmap,无需考虑bitmap在android中加载的时候oom的问题和快速滑动的时候图片加载位置错位等问题。
- Afinal的宗旨是简洁,快速。约定大于配置的方式。尽量一行代码完成所有事情。
Afinal的四大模块
FinalDB模块:android中的orm框架,一行代码就可以进行增删改查。支持一对多,多对一等查询。
FinalActivity模块:android中的ioc框架,完全注解方式就可以进行UI绑定和事件绑定。无需findViewById和setClickListener等。
FinalHttp模块:通过httpclient进行封装http数据请求,支持ajax方式加载。
FinalBitmap模块:通过FinalBitmap,imageview加载bitmap的时候无需考虑bitmap加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象。FinalBitmap可以配置线程加载线程数量,缓存大小,缓存路径,加载显示动画等。FinalBitmap的内存管理使用lru算法,没有使用弱引用(android2.3以后google已经不建议使用弱引用,android2.3后强行回收软引用和弱引用,详情查看android官方文档),更好的管理bitmap内存。FinalBitmap可以自定义下载器,用来扩展其他协议显示网络图片,比如ftp等。同时可以自定义bitmap显示器,在imageview显示图片的时候播放动画等(默认是渐变动画显示)。
使用Afinal开发框架需要用到以下权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
以上是github上的Afinal整体介绍,下面介绍一下本项目中需要到的几个功能,由于本次项目很小,仅仅用到了Afinal中的一点点功能:
1、注解方式就可以进行UI绑定和事件绑定,无需使用findViewById和setClickListener等方法,别忘了让Activity继承FinalActivity。
public class TestActivity extends FinalActivity {
@ViewInject(id=R.id.bn_click, click="testClick") Button bnClick;
@ViewInject(id=R.id.tv_show) TextView tvShow;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.test_main);
}
public void testClick(View v){
tvShow.setText("您点击了确定");
}
}
运行结果:
点击确定后-> 
2、FinalHttp的使用,接下来就要开挂了,还是用刚才的Activity,稍作修改让我们来做一下网络请求
get方法: 一行代码搞定,直接使用get方法提交请求地址,然后在相关的回调方法中进行结果操作。上面代码给出了三个回调方法
public class TestActivity extends FinalActivity {
FinalHttp fh;
String url = "http://xiaohua.hao.360.cn/m/itxt?page=1";
@ViewInject(id=R.id.bn_click, click="testClick") Button bnClick;
@ViewInject(id=R.id.tv_show) TextView tvShow;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.test_main);
fh = new FinalHttp();
}
public void testClick(View v){
fh.get(url, new AjaxCallBack<String>(){
@Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
tvShow.setText("正在请求……");
}
@Override
public void onLoading(long count, long current) {
// TODO Auto-generated method stub
super.onLoading(count, current);
//请求响应过程中会执行此方法,每隔1秒自动回调一次
tvShow.setText(current + "/" + count);
}
@Override
public void onSuccess(String t) {
// TODO Auto-generated method stub
super.onSuccess(t);
tvShow.setText(t);
}
@Override
public void onFailure(Throwable t, int errorNo, String strMsg) {
// TODO Auto-generated method stub
super.onFailure(t, errorNo, strMsg);
tvShow.setText("网络异常");
}
});
}
}
post方法:
AjaxParams params = new AjaxParams();
params.put("username", "testname");
params.put("password", "123456");
params.put("profile_picture", new File("/mnt/sdcard/test.jpg")); // 上传文件
params.put("profile_picture2", inputStream); // 上传数据流
params.put("profile_picture3", new ByteArrayInputStream(bytes)); // 提交字节流 fh.post("http://www.test.com", params, new AjaxCallBack(){......});
① onStart()请求开始时回调此方法。
② onSuccess()请求成功时回调此方法,其中“t”为返回结果。
③ onFailure()请求失败时回调此方法。
④ onLoading()在请求响应过程中,每隔1秒回调一次此方法。
执行结果如下:

3、FinalBitmap的使用。同样,加载网络图片也是就一行代码 fb.display(imageView,url)。
public void loadingImg(View v){
FinalBitmap fb = FinalBitmap.create(this);
fb.display(ivImg, "http://pic4.nipic.com/20091120/805653_183746006558_2.jpg");
}
其中,loadingImg方法是用注解方式绑定在按钮上的事件,ivImg是ImageView控件。点击按钮后就会加载一张网络图片,结果如下:

哈哈,是不是很简单,同时也很给力啊!
本项目目前设计到Afinal的一些用法就这几个,如果想了解更多可以参考:http://www.oschina.net/p/afinal
在项目开中还涉及到了另一个很给力的工具--Jackson,暂时先不介绍了,等在项目中需要到的时候再做介绍。
有了这两样工具,我们的开发工作就大大简化了很多,而且性能绝不比自己纯手工去写网络请求之类的方法性能差。当然,在实际的开发中我们不能这样暴力式的直接使用get和post方法,最好是做一下封装,这样的话既节省了工作量,减少重复代码,又保证了请求方式的规范性,在后续博文中会展开项目的详细介绍。
PS:本来打算只介绍上面这么多呢,因为在将要介绍到的项目中目前只用到上面这几个功能,不过有园友建议再介绍一下FinalDb,OK,再续上一段。
4、FinalDb的使用。
其实用Afinal操作数据也是非常方便的,仍然很好的体现着Afinal的风格,一行代码实现保存数据/读取数据。
首先建立一个实体对象,用来充当数据表角色。
public class Note {
private int id;//id属性必须要有
private String title;
private String content;
/* getter and setter方法一定要有,应为FinalDb会通过setter方法赋值*/
public int getId() {
return id;
}
public String getTitle() {
return title;
}
public String getContent() {
return content;
}
public void setId(int id) {
this.id = id;
}
public void setTitle(String title) {
this.title = title;
}
public void setContent(String content) {
this.content = content;
}
}
实体类建好了,再写一个测试Activity:
public class DbTestActivity extends FinalActivity {
FinalDb fd;
Note note;
@ViewInject(id=R.id.et_title) EditText etTitle;
@ViewInject(id=R.id.et_content) EditText etContent;
@ViewInject(id=R.id.txt_title) TextView txtTitle;
@ViewInject(id=R.id.txt_content) TextView txtContent;
@ViewInject(id=R.id.bn_save, click="saveData") Button bnSave;
@ViewInject(id=R.id.bn_read, click="readData") Button bnRead;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dbtest);
fd = FinalDb.create(this);
}
//利用Afinal注解直接在按钮上绑定事件。
public void saveData(View v){
dbSave();
}
public void readData(View v){
dbRead();
}
private void dbSave(){
note = new Note();
note.setTitle(etTitle.getText().toString());
note.setContent(etContent.getText().toString());
//利用FinalDb的save方法保存数据
fd.save(note);
}
private void dbRead(){
//利用FinalDb的findAll方法查询数据
List<Note> noteList = fd.findAll(Note.class);
txtTitle.setText("标题:" + noteList.get(0).getTitle());
txtContent.setText("内容:" + noteList.get(0).getContent());
}
}
布局文件也很简单,也一并贴出来吧。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <EditText
android:id="@+id/et_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Input title"
android:ems="10" >
<requestFocus />
</EditText> <EditText
android:id="@+id/et_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Input content"
android:ems="10" >
</EditText> <Button
android:id="@+id/bn_save"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="保存到数据库" /> <Button
android:id="@+id/bn_read"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="读取数据" /> <TextView
android:id="@+id/txt_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标题:" /> <TextView
android:id="@+id/txt_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="内容:" /> </LinearLayout>
执行结果如图,在编辑框输入内容后,单击保存到数据库按钮,程序会执行fd.save方法(如左图),然后我们单击读取数据按钮,就会从数据库中读取出来数据,并显示在下面(如右图)


然后我们在验证一下,是否真的插入了数据库,关闭程序,重新打开后直接点击读取数据按钮,会看到仍然可以读取之前保存过的内容,由于在代码中,只取了数据表中的第一行内容,所以多次保存后仍然只显示第一次写入的数据。(由于手机目前没有root,所以无法直接通过eclipse的File Explorer查看数据库,敬请谅解!)

以上只是简单介绍了一下Afinal的几个用法,希望能起到抛砖引玉的作用,好了,步入正题,在下一遍博文中将要开始咱们的项目之旅......
Android项目开发全程(二)--Afinal用法简单介绍的更多相关文章
- Android项目开发全程(四)-- 将网络返回的json字符串轻松转换成listview列表
前面几篇博文介绍了从项目搭建到获取网络字符串,对一个项目的前期整体工作进行了详细的介绍,本篇接着上篇介绍一下怎么样优雅将网络返回的json字符串轻松转换成listview列表. 先上图,看一下效果. ...
- Android项目开发全程(三)-- 项目的前期搭建、网络请求封装是怎样实现的
在前两篇博文中已经做了铺垫,下面咱们就可以用前面介绍过的内容开始做一个小项目了(项目中会用到Afinal框架,不会用Afinal的童鞋可以先看一下上一篇博文),正所谓麻雀虽小,五脏俱全,这在里我会尽量 ...
- Android项目开发全程(一)--创建工程
每个程序员都知道,项目工程的整体架构对开发有着决定性的影响,在后续的开发工作中,能不能有效的减少代码的重复量和有效的人员分工取决于前期工程整体的架构.刚参加工作还不到一个月就意识到之前做的项目在架构方 ...
- C#-Xamarin的Android项目开发(二)——控件应用
相信我,这不是一篇吐槽文章.... 基础控件 Android的控件和控件样式非常特别,它是一种内联特别高的设计模式,换句话说,它是非常烂的设计.... 但在这种特别的关系里还是有一定的规律的,下面我们 ...
- 【转】android应用开发全程实录-你有多熟悉listview?---不错
原文网址:http://www.cnblogs.com/noTice520/archive/2011/12/05/2276379.html 今天给大家带来<android应用开发全程实录> ...
- android应用开发全程实录-你有多熟悉listview
http://blog.csdn.net/notice520/article/details/7040962 今天给大家带来<android应用开发全程实录>中关于listview和ada ...
- C#-Xamarin的Android项目开发(三)——发布、部署、打包
前言 部署,通常的情况下,它其实也是项目开发的一个难点. 为什么这么说呢?因为,它不是代码开发,所以很多开发者本能的拒绝学习它. 并且一个项目配置好一次以后,部署的步骤和部署的人通常很固定,所以大部分 ...
- Android项目开发一
Android项目开发一 进度计划 1.第一周 开源中国注册账号:http://my.oschina.net/u/2511208,并上传Android HelloWorld程序代码 搭建Andro ...
- android应用开发全程实录-你有多熟悉listview?
今天给大家带来<android应用开发全程实录>中关于listview和adatper中的部分.包括listview的基本使用,listview的优化等. 我们经常会在应用程序中使用列表的 ...
随机推荐
- javascript创建对象(一)
对象定义:无序属性的集合,属性包含基本值.对象.函数,相当于一组没有特定顺序的值. 创建自定义对象最简单的方式就是: var movie=new Object(); movie.name=&qu ...
- LINUX nohup命令输入输出深浅进出
无论是否将 nohup命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中.如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中 ...
- Oracle 11g 虚拟列 Virtual Column介绍
Oracle 11G 虚拟列 Virtual Column Oracle 11G 在表中引入了虚拟列,虚拟列是一个表达式,在运行时计算,不存储在数据库中,不能更新虚拟列的值. 定义一个虚拟列的语法: ...
- ios动力特效,最重要的一点 属性保持(写了动力特效但是没效果的原因就在这里)
@property (nonatomic, strong) UIDynamicItemBehavior *square1PropertiesBehavior; @property (nonatomic ...
- OC基础-day04
#pragma mark - Day04_01_匿名对象 1. 如果函数有返回值 我们可以不使用变量接收返回值. 而是直接将函数写在要使用其返回值的地方. 2. 正常情况下.我创建对象. 是使用了1 ...
- iOS Core Animation学习总结(1)--CALayer常用属性
图层是core animation的基础, UIView之所以能显示在屏幕上,靠的是其内部的这个图层,即每个UIView 都有 CALayer,可通过UIView.layer或者[UIView lay ...
- 从string.size()和string.length()聊到长度的问题和一个关于数据结构定义的技巧
最近工作中要查看一下string的长度,然后忘了是哪个函数,所以去网上搜了一搜,决定把网上学的和其他的一些有关长度的东西在这里汇总一下, 然后就有了此帖. string 是从c语言的char数组的概念 ...
- IntelIoT技术笔记Java/Eclipse
1. 获取最新版本 使用"Team sync perspective",如果想要看到全部工程的差异,选择全部工程,右键-Team-sync with Repository:将会自动 ...
- 学习Swift--下标脚本
下标脚本 下标脚本可以定义在类(Class).结构体(structure)和枚举(enumeration)这些目标中,可以认为是访问集合(collection),列表(list)或序列(sequenc ...
- VS2013相关资料
visual studio 主页 http://msdn.microsoft.com/en-us/vstudio/aa718325.aspx vs2013 download http://www.mi ...