【Android开发】--耦合代码,设计BaseActivity

简单介绍:
       工程设计中,有很多功能具有相似性,从而导致我们在实现项目中,会写许多相似的代码,那么找到这些功能的相似性,对其特性进行耦合,提取并设计一个父类,就是一种减少重复代码劳动的方法,因为子类可以继承父类的方法,在Android开发中,可以设计BaseActivity给Activity继承 。

耦合BaseActivity的特点:
    1、版面更干净,减少了诸如生命周期日志等重复逻辑的占用版面;
    2、代码量明显减少,共通逻辑写一遍被继承就可以实现,且可以重写父类方法;
    3、缺点也有,如果产品提出了一个妖类的功能或者使用了一些第三方库,那么base可能就没有用,必须重写所有需要的业务方法;
    4、耦合和解耦没有哪个更好,都需要视具体的业务和功能进行选择和使用;
    5、不要什么都往BaseActivity中集成,学会控制自己。

举个例子:
       假设我们设计的功能Activity中,每一个都具有以下这些功能:

【Android开发】--耦合代码,设计BaseActivity

那么,假设我们要写三个新的功能Activity,那么就需要重复三次劳动:
【Android开发】--耦合代码,设计BaseActivity
但如果我们设计了BaseAcitivity,那么我们的劳动量就可以减少,让ActivityA/B/C继承BaseActivity就可以实现共通逻辑:

【Android开发】--耦合代码,设计BaseActivity


BaseActivity中建议集成以下内容:
1)生命周期的调试日志输出 
2)绑定视图
3)常用OnClick方法
4)Back方法、Toast以及Activity的操作等
5)一些统计类的地方工具集成(如友盟等提供的统计类的方法)
6)常用第三方工具(黄油刀等)

写一个简单的BaseAtivity:
package jason.aio.base;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import android.widget.Toast;


import butterknife.ButterKnife;
import jason.aio.AIO;
import jason.aio.activity.account.AccountReg;


/**
* Created by Zhu Hao on 2018/2/5.
*/

public abstract class BaseActivity extends Activity implements View.OnClickListener{
private static final String TAG = "BaseActivity";
protected Context context;
protected BaseActivity activity;
protected String className = getClass().getSimpleName();
protected abstract int getLayoutViewID(); //Layout 界面id
protected abstract void initView(); //界面配置參數,必須在setContentView之前
protected abstract void bindListener();//綁定控件
protected abstract void doCreateBusiness();//和Create有关的业务方法


@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate: " + className);
initView();

setContentView(getLayoutViewID());
context = getApplicationContext();
ButterKnife.bind(this); //黄油刀,方便我使用过程中,鼠标右键一键生成
bindListener();
AIO.getInstance().addActivityList(this); //AIO是我封装的Application的单例,管理Activity和Service使用的
doCreateBusiness();
}



@Override
protected void onStart() {
super.onStart();

}

@Override
public void onBackPressed() {
Log.i(TAG, "onBackPressed: " + className);
finish();
}

@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy: " + className);
AIO.getInstance().removeActivity(this);
}

@Override
public void onClick(View view) {

}

public void openActivity(Class cls){
startActivity(new Intent(this, cls));
}

public void openActivityAndCloseThis(Class cls){
startActivity(new Intent(this,cls));
finish();
}

public void showToast(String msg){
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}


}

以上只是举个例子

使用也简单:
package jason.aio.activity;

import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.TextInputLayout;
import android.support.v7.widget.AppCompatCheckBox;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.HashMap;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import jason.aio.AIO;
import jason.aio.R;
import jason.aio.base.BaseActivity;

/**
* Created by Zhu Hao on 2018/2/15.
*/

public class testActivity extends BaseActivity{
private static final String TAG = "testActivity";
@BindView(R.id.index_funs_login_logo_imgView)
ImageView indexFunsLoginLogoImgView;
@BindView(R.id.index_funs_login_account_editText)
EditText indexFunsLoginAccountEditText;
@BindView(R.id.index_funs_login_accountLayout_textInputLayout)
TextInputLayout indexFunsLoginAccountLayoutTextInputLayout;
@BindView(R.id.index_funs_login_forgot_txtView)
TextView indexFunsLoginForgotTxtView;
@BindView(R.id.index_funs_login_password_editText)
EditText indexFunsLoginPasswordEditText;
@BindView(R.id.index_funs_login_passwordLayout_textInputLayout)
TextInputLayout indexFunsLoginPasswordLayoutTextInputLayout;
@BindView(R.id.index_funs_login_autoLogin_checkBox)
AppCompatCheckBox indexFunsLoginAutoLoginCheckBox;
@BindView(R.id.index_funs_login_login_btn)
Button indexFunsLoginLoginBtn;
@BindView(R.id.index_funs_login_singUp_txtView)
TextView indexFunsLoginSingUpTxtView;

@Override
protected int getLayoutViewID() {
return R.layout.index_funs_login_fm;
}

@Override
protected void initView() {
requestWindowFeature(Window.FEATURE_NO_TITLE);
}

@Override
protected void bindListener() {
indexFunsLoginLoginBtn.setOnClickListener(this);

}

@Override
protected void doCreateBusiness() {

}


@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.index_funs_login_login_btn:
Log.i(TAG, "onClick: 测试");
HashMap<String,Object> hashMap = new HashMap<>();
hashMap.put("mode",1);
hashMap.put("str","asd");
hashMap.put("subTitle","知道");
EventBus.getDefault().post(hashMap);
break;
}
}

private long mPressedTime = 0;
@Override
public void onBackPressed() {
//super.onBackPressed();    //如果不想继承BaseActivity的finish功能,就把super注释掉即可,然后就可以重写返回事件方法
Log.i(TAG, "onBackPressed: 输出");
long mNowTime = System.currentTimeMillis();//获取第一次按键时间
if((mNowTime - mPressedTime) > 2000){//比较两次按键时间差
Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show();
mPressedTime = mNowTime;
} else{

AIO.getInstance().Exit();
}
}

@Override
protected void onStart() {
super.onStart();
BusUtils.EventReg(this,TAG);
}

@Override
protected void onDestroy() {
super.onDestroy();
BusUtils.EventReg(this,TAG);
}

@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(HashMap<String, Object> map ){
Log.i(TAG, "onMessageEvent: " + map.toString());
}
}
使用也较为简单,其中,控件ID绑定由于安装了黄油刀插件,直接在Layout ID上右键就可以一键生成;BusUtils是自己封装的EventBus工具。

个人不建议将StatusBar、Toolbar等封装到Base中,自己封装成工具类会更好一些,除非你的业务更适合集成到Base,做项目前,先静下心来整理一下业务,对不同功能进行相应的技术方案构选,才是最好的方法,而不是一味地捧高或贬低某种实现方法。

同时推荐两个喜欢使用application来代替Base的文章: