閱讀534 返回首頁    go 阿裏雲 go 技術社區[雲棲]


開源異步處項目Droid-Fu詳解 For Android: BetterActivity, BetterService And BetterAsyncTask

1. Droid-Fo初體驗

顯然,要了解它,首先應該說清楚它是什麼,標題中提到了它是做什麼的,但畢竟太籠統。首先我不得不先提到給我們開發者帶來巨大方便的作者Jabber,就在這裏把作者對這個項目的介紹作為一個入口吧:

https://brainflush.wordpress.com/2009/11/16/introducing-droid-fu-for-android-betteractivity-betterservice-and-betterasynctask/

通過這個地址你可以找到更多的資源和作者的介紹。關於這個項目,這裏我尊重作者的介紹:

 

Droid-Fu contains utility classes as well as some self-contained, ready to use Android components, all of which I consider useful for typical Android applications. Some of the areas for which Droid-Fu offers 

support classes include:

application life-cycle

background tasks

HTTP messaging

(remote) image handling

custom adapters

… and more. The library is still young, so expect to see a lot more stuff forthcoming!

 

由於瀏覽博客都可以得到問題的答案,我這裏想詳細提到的就是它能給大家帶來什麼方便。當然建議這之前您先了解它是做什麼的。

從我的認識,作者為什麼取名better+android提供的幾大主體生命形式,是因為它很好的解決了異步問題,簡單的說是後台任務的一個非常好選擇。也許你用過android sdk中帶有的AsyncTask,與之類似,主要將整個項目的所有異步問題予以處理。這是在項目用到的最主要的部分,如果您有什麼看法和使用經驗歡迎提出建議了!

 

2. Droid-Fo與AsyncTask

先說SDK中自帶的AsyncTask,AsyncTask提供了一個很好的機製,例如在訪問web服務器、後台處理數據時最經常使用到異步任務,AsyncTask使得我們能在出完數據後反饋到activity的方式來完成異步處理。但做多了移動項目大家都會首先考慮一個問題,就是軟件運行時候的來電中斷是否需要處理,而對於android中activity在來電進中斷狀態的機製,自然關於界麵的操作都必須要考慮這個問題。而AsyncTask無法很好的解決這個問題,並且通過測試在中斷activity的操作中都會使得AsyncTask表現出不穩定,所以才有了Droid-Fo解決這些問題。雖然可以通過定時查看和重複發送機製解決這些問題,但是代價是我們不希望看到的。Droid-Fo是在原有的一些類基礎上修改過後的產品,所以這個開源項目並不神秘,大量的引用了android自帶的SDK。說到這裏應該不必再介紹Droid-Fo的優點了。

 

 

3. Droid-Fo基本格式

 我們來做一個demo,主要完成以下功能:

 

一個含有textview的界麵,在程序被加載時就執行後台任務。

後台任務返回1,而整個task返回0和後台任務的返回值到界麵的textview顯示。

後台任務和接受到後台返回參數時需要打印debug屬性的日誌

 

首先介紹下使用Droid-Fo的基本格式:

[1].  需要在根目錄生成一個繼承自DroidFuApplication的類,如本例使用MyApplication類作為此繼承類,不需要寫入內容

[2].  在AndroidManifest.xml需要定義application的android:name標簽修改為此類,本例定義如下

 

Xml代碼  收藏代碼
  1. <application android:name=".MyApplication" android:icon="@drawable/icon" android:label="@string/app_name">  
  2.         <activity android:name=".InterfaceTest"  
  3.                   android:label="@string/app_name">  
  4.             <intent-filter>  
  5.                 <action android:name="android.intent.action.MAIN" />  
  6.                 <category android:name="android.intent.category.LAUNCHER" />  
  7.             </intent-filter>  
  8.         </activity>  
  9. </application>  

[3]. 繼承自BetterDefaultActivity的Activity,本例隻有入口Activity為InterfaceTest

[4]. 再加上繼承自BetterAsyncTask的一個task類

[5]. string.xml中如下定義

 

Xml代碼  收藏代碼
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <string name="hello">Hello World, InterfaceTest!</string>  
  4.     <string name="app_name">InterfaceTest</string>   
  5.     <string name="droidfu_progress_dialog_title">droidfu_progress_dialog_title</string>   
  6.     <string name="droidfu_progress_dialog_message">正在進行</string>   
  7. </resources>  

可以看到第3、4個為與不同string.xml的區別,如果缺少將不能正常運行。簡單說下,第3個是如果需要等待時,顯示的等待dialog的標題,第四個自然是dialog的內容

 

也許您在讀作者的介紹時沒有找到這些缺一不可的元素,那麼我的第一個小目的算是達到了,起碼能幫助你成功的完成最簡單的一個Droid-Fo應用,完成後台任務。解決了作者說明不清、缺少文檔的小小缺陷。

 

4. 項目中的Droid-Fo(demo)

代碼不多,我們直接一個個來看

(以下是我在項目中使用的框架形式,主要是將activity繼承特定接口,使得很多相似的功能可以抽象為共同的接口來處理,比如同樣為添加操作,可以在界麵端提示相同的內容;或者指定申請的類型,來判斷反饋信息的內容,這時申請格式又可能可以統一來處理,如同樣添加梨子和蘋果和傳入pearTaskId和appleTaskId來區分反饋信息的處理。從而實現了頁麵與底層邏輯的分離,將界麵處理放在activity中,而後台操作放在task中去做)

 

 AddMethod.java(提供接口方法,用來在界麵端響應反饋信息)

Java代碼  收藏代碼
  1. package org.dreamfly.interfacetest;  
  2.   
  3. public interface AddMethod {  
  4.   
  5.     public abstract void addResultHandler(int i1,Object i2);  
  6. }  
  
NewAsyncTask.java(異步task類,需要實現的方法和內容均已注釋)
Java代碼  收藏代碼
  1. package org.dreamfly.interfacetest;  
  2.   
  3. import android.content.Context;  
  4. import android.util.Log;  
  5.   
  6. import com.github.droidfu.concurrent.BetterAsyncTask;  
  7.   
  8. public class NewAsyncTask extends  
  9.         BetterAsyncTask<String, Void, String> {  
  10.   
  11.     AddMethod addMethod;  
  12.       
  13.     /** 
  14.      * Constructor 
  15.      * @param arg0  
  16.      * @param addMethod :the interface,it is also the Activity arg0 
  17.      * @param needDialog :need dialog or not when the task run in background for holding 
  18.      */  
  19.     public NewAsyncTask(Context arg0,AddMethod addMethod ,Boolean needDialog) {  
  20.         super(arg0);  
  21.         // TODO Auto-generated constructor stub  
  22.           
  23.         this.addMethod=addMethod;  
  24.         if(!needDialog){  
  25.             super.disableDialog();  
  26.         }  
  27.           
  28.     }  
  29.   
  30.     /** 
  31.      * when the handling of asynctask end, system call the after() method  
  32.      */  
  33.     @Override  
  34.     protected void after(Context arg0, String obj) {  
  35.         // TODO Auto-generated method stub  
  36.           
  37.         final Object obj2=obj;  
  38.           
  39.         Log.d(Constants.logTag, "the obj receive by method after:"+obj+".");  
  40.         addMethod.addResultHandler(0, obj2);  
  41.     }  
  42.   
  43.     @Override  
  44.     protected void handleError(Context arg0, Exception arg1) {  
  45.         // TODO Auto-generated method stub  
  46.           
  47.     }  
  48.       
  49.     /** 
  50.      * asynctask , do in backgroud 
  51.      */  
  52.     protected String doCheckedInBackground(Context context,String... obj) throws Exception{  
  53.         super.doCheckedInBackground(context, obj);  
  54.           
  55.         Log.d(Constants.logTag, "this is docheckedinbackground, i'll return 1.");  
  56.         return 1+"";  
  57.     }  
  58. }  
 
InterfaceTest.java(入口activity)

 

Java代碼  收藏代碼
  1. package org.dreamfly.interfacetest;  
  2.   
  3. import com.github.droidfu.activities.BetterDefaultActivity;  
  4.   
  5. import android.os.Bundle;  
  6. import android.widget.TextView;  
  7.   
  8. public class InterfaceTest extends BetterDefaultActivity implements AddMethod{  
  9.     /** Called when the activity is first created. */  
  10.     @Override  
  11.     public void onCreate(Bundle savedInstanceState) {  
  12.         super.onCreate(savedInstanceState);  
  13.         setContentView(R.layout.main);  
  14.           
  15.         NewAsyncTask na=new NewAsyncTask(this,this,true);  
  16.         na.execute();  
  17.     }  
  18.   
  19.     /** 
  20.      * handle the async result 
  21.      */  
  22.     public void addResultHandler(int i1, Object i2) {  
  23.         // TODO Auto-generated method stub  
  24.         TextView tv=(TextView)findViewById(R.id.text);  
  25.         tv.setText(i1+" "+i2);  
  26.     }  
  27. }  
 

好了,這裏應該可以清楚的看出這個框架的格式了。功能很簡單,想通過最簡單的形式來表現固定的格式。在真實中小型項目開發中效率和運行結果都很可觀。

 

5. demo的運行結果 

像前麵所說的demo實現的功能很簡單,這裏我們為了能更好的了解流程,貼出需求中提出的運行結果和log信息:

 

顯示結果

 

 

 

最後附件中附上工程和源碼,希望大家能快捷的上手這個還發展不完全的開源項目,解決您遇到的異步信息處理問題。好的開源項目需要大家一起去推動,希望共同努力的同時我們都可以為Droid-Fu作出一份貢獻,讓它方便更多的開發者。


最後更新:2017-04-02 17:09:26

  上一篇:go 可滑動的係統狀態欄控製麵板(wifi,bluetooth,數據通信,聲音,自動旋轉)
  下一篇:go Android ACRA3介紹