Android開源:Pluto-一個Android開發框架

對于人工智能,李開復認為,“能夠取代基本人類所有需要低于5秒鐘的工作,它都能取代。”

那么,“人工智能幫我搭建一個快速便捷通用稍稍帶點逼格的Android應用開發框架吧?”,AI也是要依賴大數據和機器學習的嘛,與其被信息瞬息萬變的時代淹沒,還不如被學習有序整理成為大數據里邊的一小部分。AI,我來介紹一下我的Android開源框架Pluto,Pluto麻煩用你稀有珍貴的男中音給全宇宙物質問聲好。

“Hello universe! I am Pluto but not far from you.”

Pluto文章結構.png

一.選擇Pluto的可能性

AI,你選擇學習Pluto原因很可能是一下重要的幾點:

  • “數據持久層”由SQLite的ORM、SharePreference和File Cache做了一層DataManager整合,提供Proxy操作。
  • “數據持久層”和“網絡層”做了一層PlutoAPIEngine整合。
  • “數據持久層”、“網絡層”和“未知業務邏輯“做了一層LogicManger整合。

這個三點相比其他通用框架做了一個大膽的結合嘗試。

AI,你選擇學習Pluto疑問很可能是一下重要幾點:

  • Pluto是不是過度封裝了,特別是“未知業務邏輯”被整合起來就失去了靈活性?
  • Pluto會不會過度處理事務,使用起來方便,閱讀起來困難,維護困難呢?
  • Pluto能不能持久更新,對未來Android新特性支持等等這些問題呢?

Pluto,主要工作是解耦分層,過度封裝那到不至于,Pluto的架構是具有極高的可擴展性。

  • 盡管聚合“為知邏輯業務層”,但是提供預留自定義業務邏輯方法,對于自定義或者特殊情況可以集成父類LogicManager,實現對應的預留方法即可。
  • 同樣的,對于持久層除了基本的增刪改查不能滿足需求,實現DataManager接口也是可以擴展的。
  • 相比其他框架具備的圖片加載框架、UI的IOC、BaseActivity、各種工具Util等等,這些都是具備的。

Pluto,因為沒有過度封裝這一說,也足夠靈活,當然也考慮了編寫代碼起來的閱讀性強弱問題。

  • 編寫起來一定有足夠信息讓你知道你主要選擇了什么樣的操作,操作的什么形式,得到的什么樣結果。
  • 維護主要維護自己的需求邏輯代碼,Pluto擴展出來的邏輯。

Pluto,會不斷更新,而且不僅僅有Android的支持,不久后會出iOS版的框架Pluto-iOS。有心學習的AI們都可以快速學習到移動開發可以這么簡單。 AI, 你準備動手學習Pluto很可能讓我尷尬的一點:

1、Pluto缺點是什么?

Pluto,缺點,比如Dialog樣式暫時沒有很多種,比如網絡層和數據持久層整合的提供的方法主要是get的支持,post方式暫時弱一些,哼哼,暫時說這么多,需要了解更多請關注的我微信公眾號minggo_dev。

AI,你開始好奇深入Pluto每個功能實現很可要思考幾點:

  • 要有哪些Android基礎知識呢?
  • 要熟知哪些通用Android第三方庫呢?
  • 要了解哪些設計模式呢?

Pluto,是一個整合框架的框架,要想一個個整合點都弄明白,以下準備更容易理解:

  • 整合框架的框架,首先要知道一些設計模式,不如工廠,抽象工廠,代理,策略,單例,觀察者等,有了這些了解,可以很快解決你讀代碼感覺很繞hold的情況,同時更好理解那里為什么要用接口,為什么要提供抽象類,為什么不直接調用等等一系列的十萬個為什么,甚至發現問題,舉一反三。
  • 第三方庫,這個都可以單獨研究,但在Pluto中就不過于強調,當然比如ButterKnife,FinalBitmap,FinalDb應有所了解。
  • Android基礎知識,那就是基礎的知識,四大主件,進程通信,Material Design有了這些就可以了。

看框架主要應該是對架構的理解和知道這個架構處理了什么問題。當然除了快、通用、高擴展,還是會有很多的指標考量,比如穩定性、容錯性、內存占用、操作速度,這些內容將會在以后文章專門整理對比總結。 二. 框架內容概要展示

Pluto內容Demo

三. 框架的各層級實現與使用 1. 框架層級

1)UIFramework:主要包括PlutoActivity,PlutoFragment,PlutoDialog,Toast,ButterKnife,UIHandler,FinalBitmap。

2)ServiceFramework:主要包括LogicManager,PlutoApiEngine,CommonAsyncTask,AsyncTaskManager。

3)NetworkFramework:主要包括ApiClient,HttpClient,StringUtils。

4)DataFramework:主要包括DataManagerProxy,DataManager,DataManagerStub,FinalDb,SharePreferenceUtil,PlutoFileCache。

2. 框架架構圖

Pluto架構圖

3. UI Framework部分

1)PlutoActivity,它繼承了AppCompatActivity作為基類整合了PlutoDialog,Toast,UIHandler,SoftInputManager,Timer,ActionBar,CommonAsyncTask的add和cancel。子類繼承PlutoActivity,就可以使用整合完暴露出來的通用方法。Pluto框架并不能直接在gradle中添加ButterKnife來完成框架外的UI綁定,需要自行在自己的項目中添加。

①樣例代碼如下:

public class PlutoActivityExample extends PlutoActivity implements OnClickListener{
     ...
     loadingDialog.show();//默認帶有PlutoDialog中的LOADING樣式

     showSoftInput();//顯示輸入法

     isNetworkConnected();//判斷網絡

     mUiHandler.sendEmptyMessage(10000);//默認weak類型Handler發送Message

     cancelAsyncTask(calculator); //觀察者cancel當前CommonAsyncTask或者LogicManager

     showHomeAsUp();//ActionBar顯示返回圖標

     //重寫PlutoActivity中handleUiMessage處理Message
     @Override
     public void handleUiMessage(Message msg) {
       super.handleUiMessage(msg);
     }

     ...
}

②效果圖如下:

PlutoActivity.gif

2)PlutoFragment,它繼承ProgressFragment(繼承Fragment)作為基類,ProgressFragment整合Loading View和show Data時序控制。PlutoFragment增加了FragmentUserVisibleController解決了在Fragment或ViewPager嵌套ViewPager時子Fragment的mUserVisibleHint屬性與父Fragment的mUserVisibleHint屬性不同步的問題,同樣具有PlutoActivity的整合的功能就不再重復。

①樣例代碼如下:

public class BlogFragment extends PlutoFragment {
 ...
 @Override
 protected void showData() {//默認是帶loading,需要在此設定何時展示數據
  setContentShown(true);
 }
 ...

 isVisibleToUser();//判斷是否在當前屏幕

 ...
}

②效果圖如下:

PlutoFragment.gif

3)PlutoDialog,它不繼承Dialog,內部構造AlertDialog,計算窗口大小制定Dialog主體內容大小,現在提供4種Dialog樣式。

①代碼樣例如下:

...

 //系統默認Dialog樣式,只提供提示信息設置,this指的是點擊按鈕的回調接口實現類
 new PlutoDialog(this, PlutoDialog.DEFAULT_EXIT, this).show();

 //系統默認Dialog樣式,this指的是點擊按鈕的回調接口實現類
 new PlutoDialog(this,PlutoDialog.DEFAULT,"Title","Dialog show message","left button","right button",this).show();

 //Loading提示對話框
 new PlutoDialog(this,PlutoDialog.LOADING).show();

 //TEXT_ONLIY只展示text,沒有任何按鈕其他的控件
 new PlutoDialog(this, PlutoDialog.TEXT_ONLIY, "Text Only").show();

 ...

②效果圖如下:

PlutoDialog.gif

4)FinalBitmap,它是Afinal框架中的圖片加載框架,這里不做過多說明。

①代碼樣例如下:

finalBitmap = FinalBitmap.create(this);
finalBitmap.configLoadingImage(R.drawable.pluto_corner);
finalBitmap.configLoadfailImage(R.drawable.pluto_corner);
finalBitmap.display(imageView2,"http://m8en.com:8877/content/charmword_thumbnail.png");

②效果圖如下:

FinalBtimap.gif

4. Data Framework部分

1)DataManagerStub,實現了DataManager(主要定義了增刪改查方法)類,作為存根類。其作用適配和擴展,能滿足指定的DataManager指定的接口外,可以自定義一下空方法,為繼承類提供可選擇性實現。

public class DataManagerStub implements DataManager {
 @Override
 public void saveData(Object key, Object object) {
 }
 @Override
 public <T> T queryData(Object key, Class<T> clazz) {
  return null;
 }
 @Override
 public <T> void deleteData(Object key, Class<T> clazz) {
 }
 @Override
 public void updateData(Object key, Object object) {
 }
}

2)FinalBitmap,是Afinal的Sqlite的ROM框架,繼承了DataManagerStub和實現saveData,queryData,deleteData和updateData方法,其中有一些小小的改動,比如能指定primary key是非自增長的任意類型,增加saveOrUpdate方法,像JavaEE中的Hibernate框架中的SaveOrUpdate方法一樣。

3)SharePreferenceUtil,是對SharePreference與xml的ORM封裝,實現基本類型、自定義的的存讀操作。它同樣繼承了DataManagerStub和實現saveData,queryData,deleteData和updateData方法。

4)PlutoFileCache,是專門處理文件的數據的存讀封裝類,承了DataManagerStub和實現saveData,queryData,deleteData和updateData方法。

5)DataManagerProxy,是一個代理、工廠、適配類,其功能是構建DataManager不同類型的實例,代理完成數據操作,適配除了DataManager固定的增刪改查外的其他特性方法,也是為了擴展性提供的一個功能職責的類。最終暴露出操作如下(Sqlite為例):

...

//通過代理構建DataType.SQLITE實例
DataManagerProxy dataManagerProxy = DataManagerProxy.getInstance(DataType.SQLITE);
//保存,如果存在就更新
dataManagerProxy.saveOrUpdate(user);
//根據primary key查詢數據返回model
User user = dataManagerProxy.queryData(1000,User.class);
//更新數據,如果不存在就保存
dataManagerProxy.saveOrUpdate(user);
//更具primary key刪除數據
dataManagerProxy.deleteData(1000,User.class);

...

6)實現效果圖如下:

DataFramework.gif

5.Network Framework部分

1)HttpClient,這個是Apache官網下載的Common-HttpClient.jar中的類。關于Apache的HttpClient更多的功能,這里不展開,Pluto主要用到的是HttpClient,GetMethod,PostMethod,HttpMethodParams這個幾個類。

2)ApiClient,這是網絡數據請求管理類,包括UA,Get和Post方法封裝,IO的讀取,超時,重連設定和返回Result<T>和Result<List<T>>類型的json與model的轉換。

3)StringUtil,主要功能是,正則匹配過濾html,友好時間提示轉換,處理網絡數據內容冗余等。

這部分內容主要利用APIClient類向PlutoAPIEngine提供網絡數據Result原始數據的獲取和第一次整理,不建議直接使用,就不提供代碼樣例。。

6.Service Framework部分

1)PlutoApiEngine,是一個整合Data Framework和Network Framework數據獲取存儲部分,提供12種獲取數據的通用的處理方式。不如,通過get的方式獲取網絡數據,指定返回類型是model類型User,緩存和網絡的關系是緩存優先,獲取網絡后保存到緩存,再返回最新數據。GET和POST為2種,返回類型Model和List為2種,緩存和網絡關系CACHE_ADVANCE_AND_NETWORK_RETURN(緩存優先,網絡獲取數據后返回),CACHE_EXPIRED_AND_NETWORK_RETURN(緩存過期,獲取網絡數據返回),ONLY_NETWORK(只獲取網絡數據)3種,它對Result數據第二次整理。2×2×3=12組合方式。如果需要增加網絡和緩存的關系組合,自行擴展即可。

2)LogicParam,它是對LogicManager需要的傳參常量名字定義,包括接口URL,URL參數,Handler的What,緩存的key等等。LogicManager通過反射獲取這些常量的值。

public class MyParam extends LogicParam {
    public static final String DOMAIN = "http://m8en.com/";
    public final class LoginParam{
        public static final int WHAT = 10000;
        public static final String URL = DOMAIN+"charmword/loginUser.action";
        public static final String CACHEKEY = "user_info";
    }
}

3)CommonAsyncTask,不是繼承AsyncTask,實現Observer,它是自定義的一個異步任務類,自定義線程池ThreadPoolExecutor,BlockingQueue,WorkerRunnable等。實現觀察者,為了提供AsyncTaskManager做增加取消全部管理。cancelAll()該方法不要寫在onDestroy()方法中,以免引起下個Activity的異步任務中斷。

4)AsyncTaskManager,繼承了Observable,只做添加CommonAsyncTask和刪除所有的CommonAsyncTask。

5)LogicManager,它繼承CommonAsyncTask,PlutoApiEngine的數據Result進行進行第三次整理,并且提供兩個擴展方法innerDoInBackgroundPre()和innerDoInBackgroundEnd(Object object),在doInBackground中分別在PlutoApiEngine獲取數據的前后調動,整個LogicManager處理過程綁定在一個異步線程CommonAsyncTask中進行。LogicManager或者LogicManager子類提供給PlutoActivity子類實例化,傳入的參數是鏈式調用。傳進來的參數其中就包括數據獲取12中情況的枚舉,這里對枚舉有特數據格式要求,以“__”為分割線,便于枚舉切割,動態選擇切割后的條件調用響應處理方法。LogicManager是整個框架的最核心的高效的部分,一句鏈式簡單的鏈式調用完成不同邏輯數據整理結果。

最終ServiceFramework部分我們只需關注LogicManager,代碼樣例:

...

new LogicManager(mUiHandler,User.class,GET__MODEL__ONLY_NETWORK)
.setParamClass(LoginParam.class)
.setParam(ParamName.PASSWORD,123456)
.setParam(ParamName.EMAIL,"minggo8en@gmail.com")
.setParam(ApiUrl.PASS, pass)
.setArg1(1)
.execute();

new LogicManager(mUiHandler,ServerURL.class,GET__LIST__CACHE_EXPIRED_AND_NETWORK_RETURN)
.setParamClass(ServerUrlParam.class)
.setCacheKey(ServerUrlParam.CACHEKEY)
.setLimitedTime(1)
.setParam(ApiUrl.PASS, pass)
.execute();

...

效果圖就是UI Framework中的效果樣例。

7. PlutoException部分

PlutoException繼承Exception實現UncaughtExceptionHandler,作為應用的全局捕捉,包括主要兩部分處理,一部分是非崩潰錯誤不做寫到errorlog文件夾中,一部分是崩潰錯誤寫到crashlog文件夾中。至于是否要彈窗提醒提交到后臺或者每次啟動應用提交錯誤信息后臺,還需根據自己項目需求,自行擴展。樣例代碼:

try{
   ...
} catch (IOException e) {
   ...
   throw PlutoException.network(e);
}

8. Flexible Utils部分

AnimationUtils

BitmapUtil

DateUtil

DisplayUtil

EncryptUtils

FastBlur

FileUtils

LogUtils

NetworkUtils

PhotoUtil

PollingUtils

SharePreferenceUtils

StringUtils

ThreadPoolUtils

每一個Util都是開發的經常需要用到的工具類,比如,LogUtils通過是否Debug模式輸出,輸出的形式可選擇為文件;DateUtil日期轉化,格式化,優化文字;DisplayUtil屏幕單位的計算,轉化。等等一些幫助開發者快速完成功能開發的工具類。

四. 框架源碼

這就是我的Android開源框架Pluto,一個致力于更完整,更快速,更穩定的MVC開源框架,AI還請你笑納。

若干年后,當一個小孩對著自己的pad喊:“What is Pluto?”,pad回答說:“Pluto is a celestial body in the solar system. But now the most relative knowledge is an architecture of Android,named Pluto-android,which enables everybody to developing app on Android platform easier...”

從此那個小孩就開始了偉大理想--下午回校一定要把小明的Lollipop搶回來。

 

 本文由用戶 surya126 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!