简单介绍:
工程设计中,有很多功能具有相似性,从而导致我们在实现项目中,会写许多相似的代码,那么找到这些功能的相似性,对其特性进行耦合,提取并设计一个父类,就是一种减少重复代码劳动的方法,因为子类可以继承父类的方法,在Android开发中,可以设计BaseActivity给Activity继承 。
耦合BaseActivity的特点:
1、版面更干净,减少了诸如生命周期日志等重复逻辑的占用版面;
2、代码量明显减少,共通逻辑写一遍被继承就可以实现,且可以重写父类方法;
3、缺点也有,如果产品提出了一个妖类的功能或者使用了一些第三方库,那么base可能就没有用,必须重写所有需要的业务方法;
4、耦合和解耦没有哪个更好,都需要视具体的业务和功能进行选择和使用;
5、不要什么都往BaseActivity中集成,学会控制自己。
举个例子:
假设我们设计的功能Activity中,每一个都具有以下这些功能:
那么,假设我们要写三个新的功能Activity,那么就需要重复三次劳动:
但如果我们设计了BaseAcitivity,那么我们的劳动量就可以减少,让ActivityA/B/C继承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的文章: