Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android App架構設計

Android App架構設計

編輯:關於Android編程

前言

Web的架構經過多年的發展已經非常成熟了,我們常用的SSM,SSH等等,架構都非常標准。個人認為,Web服務邏輯比較清晰,目的明確,流程也相對固定,從服務器收到請求開始,經過一系列的的攔截器,過濾器->被轉發到控制器手中->控制器再調用服務->服務再調用DAO獲取想要的數據->最後把數據返回給web層。哪怕中間增加一些東西,如緩存什麼的。他的模型依然是以用戶請求的線程為生命周期,經過一個個切面(層)的結構,感覺類似於流水線的結構吧。
這裡寫圖片描述
而Android App則有所不同,他沒有像用戶請求這樣一個統一的出發點,最接近的可能是來自於UI的事件,然而遠不僅僅於此。根據app不同的需求,其結構也會千差萬別,所以很難有較為統一的架構。
但是客戶端類app確實是較為常見的App類型,其結構還是有跡可循的。

常見的架構

一.MVC
mvc現在是用的人最多,同時也是Android官方的設計模式,可以說Android App原本就是MVC的,View對應布局文件xml,Controller對應Activity,Model對應數據模型。
這裡寫圖片描述
這類App一般會定義一個BaseActivity,BaseActivity內部實現了網絡的異步請求,本地數據的存儲加,數據庫訪問載等復用性較強的邏輯。邏輯控制則在對應的Activity中實現。
MVC的缺點:Activity過於臃腫,往往一個Activity幾百上千行代碼。View層的XML控制力其實非常弱,眾多的View處理還是要放在Activity進行,這樣的話,Activity就既包含了View又包含了Controller,耦合高,不利於測試擴展,可讀性也變差。


二.MVVM
用過VS開發過.net的人肯定知道MVVM的強大之處,僅需要點點鼠標,數據庫裡的信息和View的控件顯示就被簡單的綁定了。
這裡寫圖片描述
而Android的數據綁定個人認為還是不夠成熟的,用法長這樣android:text=”@{user.username}”/>
在xml裡面配置數據模型。一是控制力不夠,二是部分邏輯需要放到數據Model裡處理。


三.MVP
最近在Android上應用比較火的模式。相較於MVC,MVP將Activity中的業務邏輯抽取出來,將Activity,Fragment等作為View層,專職與界面交互。而Presenter則負責數據Model的填充和View層的顯示。View不直接與Model交互,解耦了Actiity。
這裡寫圖片描述
這樣可以做到邏輯和界面交互的完全分離,方便測試,界面升級等。代碼的可讀性也大大增加。

個人的設計

對於我自己,在我自己架構項目的時候確實遇到了一些困難,也有選擇障礙,經過一番思考。我有了自己的見解,總體還是偏向於MVP,但又有些不同。可能是MVP+MVVM(偽)吧。

首先是包結構
這裡寫圖片描述
1.View層
view層按照Android組件的分類,可以使用接口通信,也可以使用類似EventBus的事件框架進行通信
Action包就是事件實體,這裡使用的是我自己實現的事件框架。
這裡寫圖片描述


2.Model層
model層包含數據模型,實體類,以及dao,http等數據獲取得代碼。回掉的話可以使用接口,也可以使用事件框架。另外緩存也放在這裡。
這裡寫圖片描述


3.Presenter
包含Base(自己實現的Presenter框架,其實就是將Activity抽取了一層),Service包是Android組件Service
Impl是業務的實現,下面一堆I開頭的是業務接口。
這裡寫圖片描述
這裡講一下Base,Base相當於控制器,拿登陸來舉例,一個登陸操作可能涉及多個界面,多個業務邏輯單元。比如登陸,首先是請求網絡的邏輯,除此之外,登陸成功後,需要對會話,用戶基礎信息等進行持久化;還有控制器需要控制各個界面的刷新。這些都是在控制器Base中完成的,他是一組邏輯的控制單元,負責一個典型的業務,比如說登陸。


下面的重點是業務接口,例如登陸ILogin,如果自己實現,你需要寫一大堆的東西,網絡請求,異步處理,Handler,異常處理,JSON解析,顯示,洋洋灑灑至少上百行了。如果你的項目需要快速上線怎麼辦?同時你又想保持項目的邏輯結構,以後做更細致的改進,這時候就體現了接口的重要性。這裡安利我一個比較快速的實現鏈接也是我實現的一個小框架。
用起來畫風是這樣的。

public class LoginPresenter extends Presenter implements ActivityOnCreatedListener,ICallBack{

    private ILogin ILogin;

    @Override
    protected void onContextChanged(ContextChangeEvent event) {

    }

    @Override
    public void OnPresentInited(Context context) {
        ILogin = HttpProxyFactory.With(ILogin.class).setCallBack(this).setViewContent(getActivityRaw()).establish();
        getActivityInter().setOnCreateListener(this);
    }

    @Override
    public void ActivityOnCreated(Bundle savedInstanceState, final Activity activity) {
        getActivityInter().getView(R.id.btn_login)
                          .setOnClickListener(new View.OnClickListener() {
                              @Override
                              public void onClick(View v) {
                                  LoginActivity ac = (LoginActivity) activity;
                                  ac.progressDialog.show();
                                  getActivityInter().getView(R.id.btn_login).setClickable(false);
                                  EditText name = getActivityInter().getView(R.id.login_name);
                                  EditText pass = getActivityInter().getView(R.id.login_pass);
                                  ILogin.login(name.getText().toString(),pass.getText().toString());
                              }
                          });
    }


    @Override
    public void onSuccess(User user) {
        Log.e("gy",user.toString());
        getActivityRaw().finish();
        navTo(HomeActivity.class);
    }

    @Override
    public void onFailed(Throwable throwable) {
        ILoginCallBack callBack = (ILoginCallBack) getContext();
        callBack.onLogFailed(throwable.getMessage());
    }
}

你可以發現ILogin = HttpProxyFactory.With(ILogin.class).setCallBack(this).setViewContent(getActivityRaw()).establish();
這麼簡單,你的ILogin業務接口就被框架實現了,簡單的說就是用了動態代理,框架根據你在接口上綁定的注解信息,幫你動態代理處一個業務實現對象。幫你包辦了網絡請求,異步處理,異步回掉,異常處理,JSON解析,顯示等一大堆操作。
如何綁定你的需求?

ILogin接口張這樣的

public interface ILogin {
    @HttpSrcMethod(url = "/store/login",session = Global.SKEY_UNLOGIN,filters = ResultFilter.class)
    public User login(@Param("tel")String name,@Param("password")String passwd);
}

返回值模型Model User比較簡單,我們換一個比較典型的


@JsonOrm
public class ResultArea implements IHandler{

    @JsonString("name")
    private String name;
    @JsonString("id")
    private String id;
    @BindListView(CityPickerActivity.ListViewId)
    @JsonSet(name = "areas",clazz = Area.class)
    private List
child; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public List getChild() { return child; } public void setChild(List child) { this.child = child; } @Override public void handler() throws Exception { if (child == null) child = new ArrayList<>(); child.add(0,new Area(name,id)); } }

注解幾乎映射了你所有的業務接口協議,包括請求參數,URL,頭,返回值的json映射,對應View層的視圖顯示等等。

使用這種臨時解決方案之後,後期如有需求,自己再選用其它框架,或者自己實現業務接口即可,根本不需要動其他模塊,從而保證了可擴展性。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved