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。

 1 public class TestActivity extends FinalActivity {
 2     @ViewInject(id=R.id.bn_click, click="testClick") Button bnClick;
 3     @ViewInject(id=R.id.tv_show) TextView tvShow;
 4     @Override
 5     protected void onCreate(Bundle savedInstanceState) {
 6         // TODO Auto-generated method stub
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.test_main);
 9     }
10     public void testClick(View v){
11         tvShow.setText("您點擊了確定");
12     }
13 }

運行結果:               

     點擊確定后-> 

2、FinalHttp的使用,接下來就要開掛了,還是用剛才的Activity,稍作修改讓我們來做一下網絡請求

  get方法: 一行代碼搞定,直接使用get方法提交請求地址,然后在相關的回調方法中進行結果操作。上面代碼給出了三個回調方法

 1 public class TestActivity extends FinalActivity {
 2     FinalHttp fh;
 3     String url = "http://xiaohua.hao.360.cn/m/itxt?page=1";
 4     @ViewInject(id=R.id.bn_click, click="testClick") Button bnClick;
 5     @ViewInject(id=R.id.tv_show) TextView tvShow;
 6     @Override
 7     protected void onCreate(Bundle savedInstanceState) {
 8         // TODO Auto-generated method stub
 9         super.onCreate(savedInstanceState);
10         setContentView(R.layout.test_main);
11         fh = new FinalHttp();
12     }
13     public void testClick(View v){
14         fh.get(url, new AjaxCallBack<String>(){
15             @Override
16             public void onStart() {
17                 // TODO Auto-generated method stub
18                 super.onStart();
19                 tvShow.setText("正在請求……");
20             }
21             
22             @Override
23             public void onLoading(long count, long current) {
24                 // TODO Auto-generated method stub
25                 super.onLoading(count, current);
26                 //請求響應過程中會執行此方法,每隔1秒自動回調一次
27                 tvShow.setText(current + "/" + count);
28             }
29             
30             @Override
31             public void onSuccess(String t) {
32                 // TODO Auto-generated method stub
33                 super.onSuccess(t);
34                 tvShow.setText(t);
35             }
36             
37             @Override
38             public void onFailure(Throwable t, int errorNo, String strMsg) {
39                 // TODO Auto-generated method stub
40                 super.onFailure(t, errorNo, strMsg);
41                 tvShow.setText("網絡異常");
42             }
43         });
44     }
45 }

post方法:

 1     AjaxParams params = new AjaxParams();
 2       params.put("username", "testname");
 3       params.put("password", "123456");
 4       params.put("profile_picture", new File("/mnt/sdcard/test.jpg")); // 上傳文件
 5       params.put("profile_picture2", inputStream); // 上傳數據流
 6       params.put("profile_picture3", new ByteArrayInputStream(bytes)); // 提交字節流
 7 
 8       fh.post("http://www.test.com", params, new AjaxCallBack(){......});

  ① onStart()請求開始時回調此方法。

  ② onSuccess()請求成功時回調此方法,其中“t”為返回結果。

  ③ onFailure()請求失敗時回調此方法。

  ④ onLoading()在請求響應過程中,每隔1秒回調一次此方法。

 

執行結果如下:

  

3、FinalBitmap的使用。同樣,加載網絡圖片也是就一行代碼 fb.display(imageView,url)。

1 public void loadingImg(View v){
2         FinalBitmap fb = FinalBitmap.create(this);
3         fb.display(ivImg, "http://pic4.nipic.com/20091120/805653_183746006558_2.jpg");
4 } 

其中,loadingImg方法是用注解方式綁定在按鈕上的事件,ivImg是ImageView控件。點擊按鈕后就會加載一張網絡圖片,結果如下:

  

哈哈,是不是很簡單,同時也很給力啊!

本項目目前設計到Afinal的一些用法就這幾個,如果想了解更多可以參考:http://www.oschina.net/p/afinal

在項目開中還涉及到了另一個很給力的工具--Jackson,暫時先不介紹了,等在項目中需要到的時候再做介紹。

有了這兩樣工具,我們的開發工作就大大簡化了很多,而且性能絕不比自己純手工去寫網絡請求之類的方法性能差。當然,在實際的開發中我們不能這樣暴力式的直接使用get和post方法,最好是做一下封裝,這樣的話既節省了工作量,減少重復代碼,又保證了請求方式的規范性,在后續博文中會展開項目的詳細介紹。

 PS:本來打算只介紹上面這么多呢,因為在將要介紹到的項目中目前只用到上面這幾個功能,不過有園友建議再介紹一下FinalDb,OK,再續上一段。

4、FinalDb的使用。

  其實用Afinal操作數據也是非常方便的,仍然很好的體現着Afinal的風格,一行代碼實現保存數據/讀取數據。

  首先建立一個實體對象,用來充當數據表角色。

 1 public class Note {
 2     private int id;//id屬性必須要有
 3     private String title;
 4     private String content;
 5     
 6     /* getter and setter方法一定要有,應為FinalDb會通過setter方法賦值*/
 7     public int getId() {
 8         return id;
 9     }
10     public String getTitle() {
11         return title;
12     }
13     public String getContent() {
14         return content;
15     }
16     public void setId(int id) {
17         this.id = id;
18     }
19     public void setTitle(String title) {
20         this.title = title;
21     }
22     public void setContent(String content) {
23         this.content = content;
24     }
25 }

實體類建好了,再寫一個測試Activity:

 1 public class DbTestActivity extends FinalActivity {
 2     FinalDb fd;
 3     Note note;
 4     @ViewInject(id=R.id.et_title) EditText etTitle;
 5     @ViewInject(id=R.id.et_content) EditText etContent;
 6     @ViewInject(id=R.id.txt_title) TextView txtTitle;
 7     @ViewInject(id=R.id.txt_content) TextView txtContent;
 8     @ViewInject(id=R.id.bn_save, click="saveData") Button bnSave;
 9     @ViewInject(id=R.id.bn_read, click="readData") Button bnRead;
10     @Override
11     protected void onCreate(Bundle savedInstanceState) {
12         // TODO Auto-generated method stub
13         super.onCreate(savedInstanceState);
14         setContentView(R.layout.activity_dbtest);
15         fd = FinalDb.create(this);
16     }
17     
18     //利用Afinal注解直接在按鈕上綁定事件。
19     public void saveData(View v){
20         dbSave();
21     }
22     
23     public void readData(View v){
24         dbRead();
25     }
26     
27     private void dbSave(){
28         note = new Note();
29         note.setTitle(etTitle.getText().toString());
30         note.setContent(etContent.getText().toString());
31         //利用FinalDb的save方法保存數據
32         fd.save(note);
33     }
34     
35     private void dbRead(){
36         //利用FinalDb的findAll方法查詢數據
37         List<Note> noteList = fd.findAll(Note.class);
38         txtTitle.setText("標題:" + noteList.get(0).getTitle());
39         txtContent.setText("內容:" + noteList.get(0).getContent());
40     }
41 }

布局文件也很簡單,也一並貼出來吧。

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:id="@+id/container"
 4     android:layout_width="match_parent"
 5     android:layout_height="match_parent"
 6     android:orientation="vertical">
 7     
 8     <EditText
 9         android:id="@+id/et_title"
10         android:layout_width="match_parent"
11         android:layout_height="wrap_content"
12         android:hint="Input title"
13         android:ems="10" >
14         <requestFocus />
15     </EditText>
16     
17     <EditText
18         android:id="@+id/et_content"
19         android:layout_width="match_parent"
20         android:layout_height="wrap_content"
21         android:hint="Input content"
22         android:ems="10" >
23     </EditText>
24 
25     <Button
26         android:id="@+id/bn_save"
27         android:layout_width="fill_parent"
28         android:layout_height="wrap_content"
29         android:text="保存到數據庫" />
30     
31     <Button
32         android:id="@+id/bn_read"
33         android:layout_width="fill_parent"
34         android:layout_height="wrap_content"
35         android:text="讀取數據" />
36             
37     <TextView
38         android:id="@+id/txt_title"
39         android:layout_width="wrap_content"
40         android:layout_height="wrap_content"
41         android:text="標題:" />
42     
43     <TextView
44         android:id="@+id/txt_content"
45         android:layout_width="wrap_content"
46         android:layout_height="wrap_content"
47         android:text="內容:" />
48     
49 </LinearLayout>

執行結果如圖,在編輯框輸入內容后,單擊保存到數據庫按鈕,程序會執行fd.save方法(如左圖),然后我們單擊讀取數據按鈕,就會從數據庫中讀取出來數據,並顯示在下面(如右圖)

然后我們在驗證一下,是否真的插入了數據庫,關閉程序,重新打開后直接點擊讀取數據按鈕,會看到仍然可以讀取之前保存過的內容,由於在代碼中,只取了數據表中的第一行內容,所以多次保存后仍然只顯示第一次寫入的數據。(由於手機目前沒有root,所以無法直接通過eclipse的File Explorer查看數據庫,敬請諒解!)

以上只是簡單介紹了一下Afinal的幾個用法,希望能起到拋磚引玉的作用,好了,步入正題,在下一遍博文中將要開始咱們的項目之旅......


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM