Android项目框架从搭建到放弃(二)

上一篇文章介绍了我常用的一些框架,也是为我现在要讲的一个MVP小Demo做了个铺垫,没看过的客官可以瞅瞅这些常用的框架 -- Android项目框架从搭建到放弃(一)

在我写Android学习MVP架构的最简单方法的时候,我也是刚开始学习这个模式,看了不少用MVP模式写的demo,感觉各有千秋但仍不如我意。因为他们没有进行很好的优化,虽然看似减轻了Activity的负担,但是增加很多类文件,使用起来仍很费劲。

因此我自己琢磨出来一个写法,只为给大家提供一个思路

先贴一张项目结构图:


1510656-fb762862d4de5031.png
Paste_Image.png
  • Model层分为Json转换的Bean对象和View的接口,即BaseView,所有的View都共用这一个BaseView,BaseListView继承BaseView增加获取Adapter等其他方法。
  • View层就是各个Activity,Fragment,Pager页面。
  • Presenter层只有一个BasePresenter,所有的Activity和Fragment都用它来做网络请求等耗时操作,BaseListPresenter继承BasePresenter来处理有刷新和加载的列表页面,如果有其他情况可以自己写个子类继承BasePresenter来复写父类的默认加载方法或者增加其他方法(例如BaseListPresenter)。

BaseView

public interface BaseView {    
    /**     
     * 显示loading     
     */   
     void showLoading();    
   /**     
    * 隐藏loading     
    */    
    void hideLoading();    
   /**     
    * 获取更新ui的接口url     
    * @return     
    */    
    String getDefaultUrl();    
   /**     
    * 更新ui数据     
    */    
    void setViewData(String data);    
   /**     
    * 没有网络     
    */    
    void noNetWork();    
   /**     
    * 服务器异常,不是200时候的处理     
    */    
    void isNotTwohundred(BaseResponse response);
}

BaseActivity :

public abstract class BaseActivity extends AppCompatActivity implements BaseView, NetEventHandler {

    @Override
    protected void onCreate(Bundle savedInstanceState) { 
         super.onCreate(savedInstanceState);    
         synchronized (mActivities) {        
             mActivities.add(this);    
         }    
         onBeforeSetContentLayout();    
         setContentView(getLayoutId());      
         presenter = getPresenter();    
         initActionBar();    
         init(savedInstanceState);    
         initView();    
         if (isLoadDefault()) { //如果默认需要加载数据,就去请求网络
            presenter.loadDefaultData();    //请求网络操作在presenter中,结果会回调给activity
         }
   }
//省略...
}

BasePresenter

public class BasePresenter {    
  public Context context;    
  public BaseView view;    
  public BaseListView listView;    
  public BasePresenter(Context context, BaseListView baseListView) {     
     this.context = context;        
     this.listView = baseListView;    
  }    
  public BasePresenter(Context context, BaseView view) {       
     this.context = context;       
     this.view = view;    
  }    
/**     
* 默认加载页面数据    
 */    
  public void loadDefaultData(){        
  String url = view.getDefaultUrl();        
  if(!checkUrl(url)) return;        
  view.showLoading(); 
  OkHttpUtils.get().url(url).headers(RequestHeaders.headers()).tag(url).build().execute(new StringCallBack(context) {            
  @Override            
  public void onResponse(BaseResponse response, int id) {    
     if(response!=null&&response.isOk()){    
         view.setViewData(response.getData());                
     }else if(response!=null){                    
         view.isNotTwohundred(response);                
     }          
  }            
  @Override            
  public void onError(Call call, Exception e, int id) {       
       super.onError(call, e, id);                             
       view.noNetWork();            
  }            
  @Override            
  public void onAfter(int id) {                
    super.onAfter(id);                
    if(view!=null){                    
       view.hideLoading();               
    }            
  }        
  });    
 }    
//省略部分请求方法...
  private boolean checkUrl(String url){        
     if(TextUtils.isEmpty(url)){            
        LogUtils.d("url为空,不加载数据");           
        return false;        
     }else if(!url.startsWith("http")){            
        LogUtils.d("url类型错误");            
        return false;        
    }       
    if(TDevice.getNetworkType()==0){            
       LogUtils.e("网络连接异常");            
       view.noNetWork();            
       return false;        
    }        
    return true;   
  }       
}

这里贴出部分代码,大体的思路就是我不再像之前那样,为每一个View都去创建一个presenter和model,使用公用的,如果有特殊要求继承一个就行了。
举个Activity页面的小栗子:

public class DemoActivity extends BaseActivity {    
    private TextView mTvName;    
    @Override    
    protected int getLayoutId() {        
       return R.layout.activity_demo;    
    }    
   /**     
    * 如果本页面不需要加载数据返回null即可     
    * @return     
    */    
   @Override    
   public String getDefaultUrl() {  return HttpManager.DEMO_URL;  }    
   @Override    
   protected void initView() {        
      mTvTitle.setText("Demo");        
      mTvName = getView(R.id.mTvName);    
     //执行一个get请求,presenter.getRequest()
     mTvName .setOnClickListener(v->getRequest());
     //执行一个post请求,presenter.postRequest()
     mTvName .setOnClickListener(v->postRequest());
   }    
   @Override    
   public void setViewData(String data) {   
     DemoBean demoBean = GsonTools.changeGsonToBean(data, DemoBean.class);
     mTvName.setText(demoBean.getName());
   }

  private void getRequest() {    
  presenter.getRequest(HttpManager.DEMO_URL, new StringCallBack(this) {        
     @Override        
     public void onResponse(BaseResponse response, int id) {            
        mTvName.setText(response.getData());        
     }    
   });
  }

  private void postRequest() {    
    if(mTvName.getText().toString().length()<10){        
    UIUtils.showToast("用户名太短,请重新输入");        
    return;   
    }    
    presenter.postRequest(HttpManager.DEMO_URL, getRequestBody(), new StringCallBack(this) {        
      @Override        
      public void onResponse(BaseResponse response, int id) {            
        mTvName.setText(response.getData());        
     }   
   });
  }
}

这就是我自己琢磨的一种MVP写法,大家可以参考一下,其实写的也不是很完善,还有很多可以优化的地方,代码已经上传至GitHub,有什么建议欢迎留言评论。

GitHub地址 ZzMvp 大爷随手start一下(*  ̄3)(ε ̄ *)

JitPack把我的基类和常用的工具类整成了一个library,只是为了日后自己使用方便,会一直来优化的,只需关联一下,一行代码搭建起来一个项目框架!(扩展性会逐渐增强)
使用方法:

//Add it in your root build.gradle at the end of repositories:
allprojects { 
  repositories { ...            
     maven { url "https://jitpack.io" 
     } 
  }
}
//Add the dependency [Latest release](https://github.com/itzhong/ZzMvp/releases/latest)
dependencies { 
   compile 'com.github.itzhong:ZzMvp:V1.0.2' 
}

下面就是我用这个library来写的一个DemoGIF:

1510656-108fdf9d04c12e86.gif
demo.gif

谢谢观看。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值