Android:如何编写“万能”的Activity

前言

自己android开发也有些年头了,每每回想起作为初学者的时候自己写的代码,自己会有种喷自己的冲动,代码写的太渣了。因此想着自己要总结下以前代码中的不合理的地方,希望能给初学者一些帮助。我希望这是一个系列的文章。

本节内容

一个“万能”的Activity是什么样子,“万能”的Activity有哪些不好的地方

开始编写“万能”的Activity

作为了一个初学者,有可能会有好多的朋友把Activity写的很“万能”,当然没有更好。那我就以一个登陆模块为例子,来说说一个“万能”的Activity是怎么产生的,以下代码多为伪代码。

编写activity_login.xml文件,这里就简单写下伪代码:

 一个输入用户账号的 EditText
 一个输入密码的 EditText
 一个登陆按钮 Button

编写LoginActivity,LoginActivity包含初始化activity_login.xml中views的功能,还包含给登陆按钮加监听器的功能,下面看下关键的代码片段

 public LoginActivity extends Activity{
  private EditText mUserNameView, mPasswordView;
  private Button mLoginView;
  //该方法会被onCreate方法调用
  public void initViews(){
   .......
   各种findViewById.....代码
   //给登陆按钮加监听器
   mLoginView.OnClickListener(new View.OnClickListener() {
   @Override
    public void onClick(View v) {
   }
   });
  }
 }

现在的LoginActivity中的代码是不是还很清爽,干净。它只做与UI相关的工作。

具有验证功能的LoginActivity

那接着要在登陆按钮的监听器方法实现验证账号,密码是否有效的功能,继续接着完善代码

 mLoginView.OnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
  String userName = mUserNameView.getText();
  String password = mPasswordView.getText();
   //验证用户输入的用户名,密码是否合法
  if(!validate(userName) || !validate(password)){
   告诉用户输入的用户名或密码不合法,并做一些其他的工作
   }
  }
 });
 //验证给定的字符串是否合法,true 合法,false 不合法
 private boolean validate(String str){

 }

现在的LoginActivity已经有业务代码出现了,我们该实现登陆功能了。

具有登陆功能的LoginActivity

在监听器中增加登陆功能

 mLoginView.OnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
  验证用户输入的用户名,密码是否合法代码...
  if(都合法){
   //开始登陆
   login(userName,password);
  }
  }
 });
 //登陆方法,用伪代码来写下网络请求
 private void login(String userName,String password){
  HttpClient.getInstance().login(userName,password,
   new ResponseListener(){
    public void failed(Failed failed){
     做失败相关的处理工作,比如给用户提示
     把密码输入框清空,还比如登陆次数限制等
    }
    public void success(Response response){
     对数据进行解析,跳转到app主页或其他界面
    }
   });
 }

具有数据解析,存储功能的LoginActivity

当我把登陆功能做好后,这时候产品又提了新需求,需要在用户登陆成功后,把用户相关的数据返回,并保存。那没辙只能按要求来做,但是幸运的是需求很简单,只需要修改下登陆成功方法就ok。

 public void success(Response response){
  做成功相关的处理工作
  //暂且把用户信息的类叫做UserInfo,从json中解析数据,假设response.getContent()存在
  String jsonContent = response.getContent();
  JsonObject jsonObject = new JsonObject(jsonContent);
  UserInfo userInfo = new UserInfo();
  userInfo.name = jsonObject.optString("name");
  userInfo.userId = jsonObject.optString("userId");
  其他字段的解析......
  //保存userInfo信息到数据表中,假设userDatabase已经存在
  userDatabase.save(userInfo);
  跳到app的主页
 }

到此,登陆功能开发完毕,LoginActivity最后的代码是这样

 public LoginActivity extends Activity{
  private EditText mUserNameView, mPasswordView;
  private Button mLoginView;
  public void initViews(){
   .......
   各种findViewById.....代码
   //给登陆按钮加监听器
   mLoginView.OnClickListener(new View.OnClickListener() {
   @Override
    public void onClick(View v) {
    String userName = mUserNameView.getText();
    String password = mPasswordView.getText();
    //验证用户输入的密码是否合法
    if(!validate(userName) || !validate(password)){
     告诉用户输入的用户名或密码不合法
    } else{
     //开始登陆
     login(userName,password);
    }
   }
   });
  }
  //登陆方法,用伪代码来写下网络请求
  private void login(String userName,String password){
  HttpClient.getInstance().login(userName,password,
   new ResponseListener(){
    public void failed(Failed failed){
     做失败相关的处理工作,比如给用户提示
     把密码输入框清空,还比如登陆次数限制等
    }
    public void success(Response response){
     做成功相关的处理工作
     //暂且把用户信息的类叫做UserInfo,从json中解析数据,假设response.getContent()存在
     String jsonContent = response.getContent();
     JsonObject jsonObject = new JsonObject(jsonContent);
     UserInfo userInfo = new UserInfo();
     userInfo.name = jsonObject.optString("name");
     userInfo.userId = jsonObject.optString("userId");
     其他字段的解析......
     //保存userInfo信息到数据表中,假设userDatabase已经存在
     userDatabase.save(userInfo);

     跳到app的主页
    }
   });
  }
  //验证给定的字符串是否合法,true 合法,false 不合法
  private boolean validate(String str){
  }
 }

到此登陆模块功能已经开发完成,LoginActivity由开始的清爽,干净的只关心U的代码,变成了现在的“万能”Activity,LoginActivity都做了哪些工作:

  • 处理UI
  • 处理用户名,密码合法性验证业务
  • 处理数据解析,数据存储

当然你会说现在的LoginActivity的代码也就将近100行,修改起来还是很容易的,但是随着业务的增长,谁能保证LoginActivity代码不会越来越多,包含的业务代码不会更多。LoginActivity只是"万能"Activity的一个缩影而已。

万能是好事情,但是得看万能是通过什么方式实现的,假如是通过把好多小功能分散到各自的类中,然后万能类通过把这些小类组合在一起的万能是真材实料的万能。若是通过把好多小功能全部放在一个类中使得这个类变的“万能”了,这种“万能”是不好的。

“万能”Activity缺点

我总结下“万能”Activity缺点

  • 引起"万能"Activity的变化因素很多,所以动不动就得修改它,没办法使得由于修改引入的bug的机率降到最低。
  • 业务功能没法复用
  • 这样的Activity可维护性,可阅读性都不好,耦合很高。

所以为了以后长远考虑,遇到“万能”Activity一定要大胆的重构,虽然当前重构需要花很多时间,但是以后是一劳永的,因此让“万能”Activity不在万能,让Activity只做与UI相关的工作就足够了。

总结

关于“万能”Activity的事情就聊到这,请看Android:“万能”Activity重构篇

代码清爽,干净了,阅读起来精神倍儿爽,一口气阅读100行不成问题!

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

(0)

相关推荐

  • Android实现Activity水平和垂直滚动条的方法

    本文实例讲述了Android实现Activity水平和垂直滚动条的方法.分享给大家供大家参考,具体如下: <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="

  • 详解Android开发中Activity的四种launchMode

    Activity栈主要用于管理Activity的切换.当使用Intent跳转至某个目标Activity,需要根据目标Activity的加载模式来加载. Activity一共有以下四种launchMode: 1.standard:默认,每次使用Intent跳转到目标Activity时都创建一个新的实例.坏处是每次进入都要创建新的实例,执行OnCreate方法. 2.singleTop:如果要跳转的目标Activity正好在task的顶部(说明当前肯定不在目标task里,例如我在微信首页,然后想使用

  • Android判断Activity是否在最上层的方法

    本文实例讲述了Android判断Activity是否在最上层的方法.分享给大家供大家参考,具体如下: private boolean isTopActivity(Activity activity) { ActivityManager am = (ActivityManager)getSystemService(ACTIVITY_SERVICE); ComponentName cn = am.getRunningTasks(1).get(0).topActivity; return cn.get

  • Android开发中Activity创建跳转及传值的方法

    在Android系统的江湖中有四大组件:活动(Activity), 服务(Service), 广播接收器(Broadcast Reciver)和内容提供者(Content Provider). 今天所介绍的就是Android开发中的四大组件之一:Activity,其他那三大组件以后再进行介绍.说道Android中的Activity,如果你做过iOS开发的话,Activity类似于iOS中的ViewController(视图控制器).在应用中能看到的东西都是放在活动中的.活动是安卓开发比较重要的东

  • Android编程中activity启动时出现白屏、黑屏问题的解决方法

    本文实例讲述了Android编程中activity启动时出现白屏.黑屏问题的解决方法.分享给大家供大家参考,具体如下: 默认情况下 activity 启动的时候先把屏幕刷成白色,再绘制界面,绘制界面或多或少有点延迟,这段时间中你看到的就是白屏,显然影响用户体验,怎么消除呢? 在 Activity theme 设置style 即可 <style name="AppTheme" parent="android:Theme.Light.NoTitleBar">

  • Android中fragment与activity之间的交互(两种实现方式)

    (未给Fragment的布局设置BackGound) 之前关于Android中Fragment的概念以及创建方式,我专门写了一篇博文<详解Android中Fragment的两种创建方式>,就如何创建Fragment混合布局做了详细的分析,今天就来详细说道说道Fragment与宿主Activity之间是如何实现数据交互的. 我们可以这样理解,宿主Activity中的Fragment之间要实现信息交互,就必须通过宿主Activity,Fragment之间是不可能直接实现信息交互的. Fragmen

  • Android:“万能”Activity重构篇

    前言 写Android:如何编写"万能"的Activity的这篇文章到现在已经好久了,但是由于最近事情较多,写重构篇的计划就一直被无情的耽搁下来了,借这几天还算有点空余时间,把自己这桩心事了解下. 其实大家也知道Android:如何编写"万能"的Activity的这篇文章只是个引子,其实我真正想引出的是mvp设计模式,因为最近自己最近在用mvp做项目,自己对mvp有一些感悟,因此我将用mvp进行"万能"activity的重构. 同时也有一些朋友与

  • Android开发中关于获取当前Activity的一些思考

    在Android开发过程中,我们有时候需要获取当前的Activity实例,比如弹出Dialog操作,必须要用到这个.关于如何实现由很多种思路,这其中有的简单,有的复杂,这里简单总结一下个人的一些经验吧. 反射 反射是我们经常会想到的方法,思路大概为 获取ActivityThread中所有的ActivityRecord 从ActivityRecord中获取状态不是pause的Activity并返回 一个使用反射来实现的代码大致如下 public static Activity getActivit

  • Android activity堆栈及管理实例详解

    本示例演示如何通过设置Intent对象的标记,来改变当前任务堆栈中既存的Activity的顺序. 1. Intent对象的Activity启动标记说明: FLAG_ACTIVITY_BROUGHT_TO_FRONT 应用程序代码中通常不设置这个标记,而是由系统给单任务启动模式的Activity的设置. FLAG_ACTIVITY_CLEAR_TASK 如果给Intent对象添加了这个标记,那么在Activity被启动之前,会导致跟这个Activity关联的任何既存的任务都被清除.也就是说新的Ac

  • Android实现在子线程中更新Activity中UI的方法

    本文实例讲述了Android实现在子线程中更新Activity中UI的方法.分享给大家供大家参考,具体如下: 在Android平台下,进行多线程编程时,经常需要在主线程之外的一个单独的线程中进行某些处理,然后更新用户界面显示.但是,在主线线程之外的线程中直接更新页面显示的问题是:系统会报这个异常: ERROR/AndroidRuntime(1222): android.view.ViewRoot$CalledFromWrongThreadException: Only the original

随机推荐