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的优化等. 我们经常会在应用程序中使用列表的 ...
随机推荐
- ASCII 码表对照
ASCII码表 ASCII码大致可以分作三部分组成.第一部分是:ASCII非打印控制字符第二部分是:ASCII打印字符:第三部分是:扩展ASCII打印字符 第一部分:ASCII非打印控制字符表 ASC ...
- Cocos2d-x 学习资料收集
框架源代码: http://code.google.com/p/cocos2d-x/downloads/list 搭建环境 http://blog.csdn.net/ccf19881030/artic ...
- JavaScript设置右下角悬浮窗
很多时候,我们需要设置一个dom节点到浏览器窗口的右下角.我们需要那个元素可以在窗口Scroll滚动或者变换大小resize的时候都可以保持浮动在那个位置.这个时候,我在网上看了看,发现很多框架什么啊 ...
- CSAPP Lab2: Binary Bomb
著名的CSAPP实验:二进制炸弹 就是通过gdb和反汇编猜测程序意图,共有6关和一个隐藏关卡 只有输入正确的字符串才能过关,否则会程序会bomb终止运行 隐藏关卡需要输入特定字符串方会开启 实验材料下 ...
- transcode_step()在转码过程中对pts、dts、duration的处理
对pts.dts.duration的处理主要集中在两大函数里面 1.process_input()读入数据并处理,放到滤镜里面 2.reap_filters()从滤镜读出数据,处理后写入文件 proc ...
- JS判断浏览器类型以及版本号
<script type="text/javascript"> (function(){ window.nav={}; ...
- python运维开发之第二天
一.模块初识: 1.模块定义 python是由一系列的模块组成的,每个模块就是一个py为后缀的文件,同时模块也是一个命名空间,从而避免了变量名称冲突的问题.模块我们就可以理解为lib库,如果需要使用某 ...
- #Leet Code# Unique Tree
语言:Python 描述:使用递归实现 class Solution: # @return an integer def numTrees(self, n): : elif n == : else: ...
- str、__str__ 、repr、 __repr__、``
内建函数str()和repr() 或反引号操作符(``)可以方便地以字符串的方式获取对象的内容.类型.数值属性等信息. str()函数得到的字符串可读性好(故被print调用),而结果通常无法用eva ...
- 2016030204 - git和github结合
1.下载和安装git客户端 参考:http://www.cnblogs.com/zhtzyh2012/p/5232291.html 2.github上创建项目 参考:http://www.cnblog ...