专栏名称: 程序员技术
最有影响力的程序员自媒体,关注程序员相关话题:程序人生、IT技术、IT职场、学习资源等。
目录
相关文章推荐
OSC开源社区  ·  30个小确幸(程序员版) ·  昨天  
程序员小灰  ·  Manus,又一国产AI封神了,一码难求! ·  3 天前  
OSC开源社区  ·  三句话让老板直接给我主动放假 ·  4 天前  
51好读  ›  专栏  ›  程序员技术

一套快速高效的开发框架 EasyAndroid

程序员技术  · 公众号  · 程序员  · 2018-01-10 19:01

正文

点击上方“ 程序员共读 ”,选择“置顶公众号”

关键时刻,第一时间送达!

类库介绍 EasyAndroid

  • 现在Android的框架很多,第三方库也很多,当做一个项目的时候,会考虑怎么整合那么多的资源,以达到复用快速开发。

  • 今天要说的这个框架就是整合了主流Retrofit2网络层封装、Fresco图片加载、都使用OKHTTP3进行网络处理、使用MVP架构,来快速灵活开发复用我们的项目。

框架说明

Retrofit2

为什么要使用它呢?我们来想想如果不使用它的话,我们直接操作OKHTTP3的网络请求,还需要做哪些操作?当发送请求的时候,来封装要以get或者post方式发送,然后回来了GJSON解析成我们需要的实体对象,还要看返回的数据相应码等等,来正确解析我们的数据,那么Retrofit2就是为了高效解决这些事情的,当然Retrofit2不止这些功能,具体大家可看API。

Fresco

比较了一些主流的图片加载以及各种对比,Fresco算是综合比较好的,支持较多,更新及时。

OKHTTP3

不解释了 大家都在用

Other类库

都是一些用的比较多的,Cookie自动管理、View注入Butterknife、以及RecycleView下拉刷新BaseRecyclerViewAdapterHelper、Utilcode工具库、Logger日志库 大家以前没用过的可以关注下 都很好用 灵活

MVP 架构思想

下面重点说一下MVP的Clean模式,现在MVP很火,大行其道,不搞一套MVP架构都感觉缺少点啥,哈哈,为什么呢?MVP难道就是简单的加了一个Presenter层吗?显然不是,它是一种思想,如果简单的一个应用每个Activity类中500行搞定,还需要MVP吗?我觉得就不适合了。越大型的APP、越复杂的APP才会让你觉得MVP的好。怎么做到让代码各司其职。

MVP Clean模式

上面这张图就是Clean的架构,为什么需要Clean架构呢,我们来想想,我们把业务逻辑部分都放到了Presenter层,如果这个页面做的逻辑很多,十来个业务操作(请求数据,数据库操作等),这样Presenter也会非常庞大,既然臃肿,我们继续抽象,在Presenter层下面在加一层Use Cases Domain层,专门处理增删改查等任务岂不业务更清晰明了,Presenter只需要执行相关UseCases任务,操作完回调处理就OK了。

MVP Dagger2模式

Dagger2又是个什么东东?我想说你写了Activity或者Fragment依赖Prensenter,然后呢Clean模式又让Presenter依赖UseCases,每次new一个实例进去,然后传递啊等等,想想都累,那么Dagger2可以帮你生成这些实例,你依赖啥,我注入啥,这就是它的精髓依赖注入,不止这些,第三方库,以及其它的提供者都可以进行注入,只要你需要,还有我们的Presenter对象的实例生命周期你怎么管理,UseCases层的对象呢,这一切Dagger2可以帮你做到,可以自定义Scopes,java自动帮你处理

还有一点差点忘了为什么叫Dagger2,版本号2呢,因为它2,哈哈,因为Dagger1使用的是运行时反射机制,这样会影响性能,Dagger2使用编译时自动生成对应代码,直接运行性能不会受到影响。

怎么使用这个库

DEMO代码结构图



在app module里面common包里面包含了业务逻辑层需要实现的代码演示,大家拷贝到自己项目中就行了,里面的base包包含基本的Activity、Fragment封装,我们用的时候只要在继承的时候指定需要的Presenter,会自动帮我们生成这个Presenter实例。

public class LoginActivity extends BaseActivity

di包,就是我们的dagger2使用包了,在这里面提供我们的实例,生成我们通用的注入器,不懂不要紧,不要关心,拿过去用就行了,只用来做一些presenter、task、全局实例的注入、其它大可不必用这个,本来是为了增加代码健壮性、提高效率的不能本末倒置了。要你做的就是在ActivityCommonComponent或者FragmentCommonComponent中注入我们要添加的Activity或者Fragment就行了。

/**
* Activity注入器
* @author wujiajun
*/
@ActivityScope
@Component(dependencies = AppCommonComponent.class, modules = {ActivityModule.class})public interface ActivityCommonComponent extends ActivityComponent {
   void inject(LoginActivity activity);    
   void inject(MainActivity activity);
}

net就是Retrofit2封装 ApiService包含全部的接口请求,包括请求参数、请求方式、地址、文件上传、下载,请求格式,都可以注解操作。

    /**
    * 获取注册验证码    
    */
   
   @FormUrlEncoded    
   @POST(HOST + "app/sendSMS.do")    
   Call getVerifyCode(@Field("username") String username, @Field("password") String pwd);

AppHttp就是对我们的接口进行调用处理

    public void getVerifyCode(String username, String pwd, final Http.HttpCallback callback) {
           Call call = apiService.getVerifyCode(username, pwd);        
           call.enqueue(new Http.CallbackDefault(callback));        
           call.request();    
   }

module里面拿login来举例吧 LoginActivity对LoginPresenter的依赖,以及LoginPresenter对LoginContract.View的依赖,都在类继承的时候指定就好了,会自动帮你生成,不需要传递。

/**
* 登录Activity
*
* @author wujiajun
*/

public class LoginActivity extends BaseActivity implements LoginContract.View {    
   
   @BindView(R.id.set_user_name)    
   EditText setUserName;    
   @BindView(R.id.set_pwd)    
   EditText setPwd;    
   @BindView(R.id.set_verify_code)    
   EditText setVerifyCode;    
   @BindView(R.id.get_verify_code)    
   TextView getVerifyCode;    
   @BindView(R.id.tv_login)    
   TextView tvLogin;    
   @BindView(R.id.tool_bar)    
   Toolbar toolbar;    
   
   @Override    
   protected void initInject() {        
       getActivityComponent().inject(this);    
   }    
   
   @Override    
   protected void initEventAndData() {
       toolbar.setLogo(R.mipmap.icon_app);        
       toolbar.setTitle(R.string.app_name);        
       toolbar.setTitleTextColor(ContextCompat.getColor(this, R.color.white));        
       toolbar.setTitleMarginStart(getResources().getDimensionPixelSize(R.dimen.padding_size_30));        
       setSupportActionBar(toolbar);    
   }    
   
   @Override    
   protected int getContentView() {
       return R.layout.activity_login;    
   }    
   
   @OnClick({R.id.get_verify_code, R.id.tv_login})    
   public void onClick(View view) {        
       switch (view.getId()) {          
         case R.id.get_verify_code:  
               getPresenter().getVerifyCode(setUserName.getText().toString(), setPwd.getText().toString());                
               startActivity(new Intent(this, MainActivity.class));
               break;            
         case R.id.tv_login:                
               getPresenter().login(setUserName.getText().toString(), setPwd.getText().toString(), setVerifyCode.getText().toString());                
               break;        
        }    
     }
 }

Presenter也是一样,关注于Task的执行

/**
* Login Presenter
* Created by wujiajun on 17/4/7.
*/
public class LoginPresenter extends BasePresenter implements LoginContract.Presenter {  

   @Inject    
   GetVerifyCodeTask mGetVerifyCodeTask;    
   @Inject    
   LoginTask mLoginTask;    
   
   @Inject    
   public LoginPresenter() {    
   }    
   
   @Override    
   public void getVerifyCode(String userName, String pwd) {
        mGetVerifyCodeTask.setUserName(userName);        
        mGetVerifyCodeTask.setPwd(pwd);        
        mGetVerifyCodeTask.setCallback(new UseCase.Callback() {
        
           @Override            
           public void success(BaseStatus baseStatus) {      
               getView().toast("getVerifyCode success!");            
           }            
           
           @Override            
           public void fail() {  
               getView().toast("getVerifyCode fail!");            
           }        
       });        
       getThreadExecutor().execute(mGetVerifyCodeTask);    
  }    
 
  @Override    
  public void login(String userName, String pwd, String verifyCode) {
      
      getView().showLoading();        
      mLoginTask.setUserName(userName);        
      mLoginTask.setPwd(pwd);        
      mLoginTask.setVerifyCode(verifyCode);        
      mLoginTask.setCallback(new UseCase.Callback()
{
            @Override            
            public void success(LoginResponse loginResponse) {
                 getView().toast("login success!");            
           }          
           @Override            
           public void fail() {    
              getView().toast("login fail!");            
           }        
        });        
        getThreadExecutor().execute(mLoginTask);    
     }
  }

domain层只关注于怎么完成这个任务 请求验证码或者登陆操作

/**
* 获取验证码任务
*
* @author wujiajun
*/
public class GetVerifyCodeTask extends AbstractUseCase {
   String publicKey = "11";    
   String userName;    
   String pwd;  
   
   @Inject    
   AppHttp appHttp;    
   
   @Inject    
   public GetVerifyCodeTask() {    
   }    
   
   @Override    
   public void run() {  
       appHttp.getVerifyCode(userName, SecretUtils.encryptByPublicKey(pwd, publicKey), new Http.HttpCallback() {
           @Override            
           public void onResponse(BaseStatus baseStatus) {    
               getCallback().success(baseStatus);            
           }            
           
           @Override            
           public void onFailure(Throwable t) {        
               getCallback().fail();            
           }        
       });    






请到「今天看啥」查看全文