我们知道,在大多数的应用型APP的平时开发中,Android四大组件里面,用的最多的可能就是Activity,一个Activity里面一般都要实现接收(传递)变量、初始化界面、获取网络数据等操作,为了避免将Activity变成一个上帝类(什么事情都做),我们应该使用面向对象思想,将共有的逻辑向上抽取,形成一个Activity类的体系。
一般而言,与业务无关的逻辑,放在顶层,我们命名BaseActivity,而与业务有关的逻辑放在第二层,命名AppBaseActivity,它继承BaseActivity,而其他的Activity,都继承AppBaseActivity
public abstract class BaseActivity extends AppCompatActivity{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
public abstract class AppBaseActivity extends BaseActivity{
}
上面就是基础框架,现在我们开始组别丰富它吧。
重构Activity的onCreate方法
根据大多数Activity都要实现的传递变量、初始化界面、获取网络数据等操作,我们重新定义BaseActivity的onCreate方法,让子类去实现。
public abstract class BaseActivity extends AppCompatActivity{
@Override
public void onCreate(Bundle savedInstanceState) {
requestManager = new RequestManager(this);
super.onCreate(savedInstanceState);
initVariables();
initViews(savedInstanceState);
loadData();
}
protected abstract void initVariables();
protected abstract void initViews(Bundle savedInstanceState);
protected abstract void loadData();
}
实现Activity的pwd
在linux中,我们可以使用pwd命名来查看当前所在路径,同样,在平时的开发调试中,想要知道当前在哪个Activity上很有必要,因此,我们修改BaseActivity代码,
public abstract class BaseActivity extends AppCompatActivity{
@Override
public void onCreate(Bundle savedInstanceState) {
requestManager = new RequestManager(this);
super.onCreate(savedInstanceState);
Log.d("pwd",getClass().getSimpleName());
initVariables();
initViews(savedInstanceState);
loadData();
}
protected abstract void initVariables();
protected abstract void initViews(Bundle savedInstanceState);
protected abstract void loadData();
}
偷吃完请擦嘴
当一个Activity退出(弹出栈)时,应该将它所有的请求(可能没有做完)都取消,因此我们需要一个requestManager来存放当前的请求
public class RequestManager {
ArrayList<HttpRequest> requestList = null;
public RequestManager(final BaseActivity activity) {
requestList = new ArrayList<HttpRequest>();
}
public void addRequest(final HttpRequest request) {
requestList.add(request);
}
public void cancelRequest() {
if ((requestList != null) && (requestList.size() > 0)) {
for (final HttpRequest request : requestList) {
if (request.getRequest() != null) {
try {
request.getRequest().abort();
requestList.remove(request.getRequest());
} catch (final UnsupportedOperationException e) {
e.printStackTrace();
}
}
}
}
}
}
而在BaseActivity中,使用RequestManager
protected RequestManager requestManager = null;
public RequestManager getRequestManager() {
return requestManager;
}
@Override
public void onCreate(Bundle savedInstanceState) {
requestManager = new RequestManager(this);
super.onCreate(savedInstanceState);
initVariables();
initViews(savedInstanceState);
loadData();
}
protected abstract void initVariables();
protected abstract void initViews(Bundle savedInstanceState);
protected abstract void loadData();
protected void onDestroy() {
if (requestManager != null) {
requestManager.cancelRequest();
}
super.onDestroy();
}
protected void onPause() {
if (requestManager != null) {
requestManager.cancelRequest();
}
super.onPause();
}
更优雅的实现startActivity(intent)
一般页面跳转,都是如下写法:
Intent intent = new Intent(Person1Activity.this,Person2Activity.class);
intent.putExtra("name","kevin");
startActivity(intent);
这个写法是非常正确的,但是按照设计模式的看法,这段代码对是Person2Activity实例的强依赖,感觉不舒服,那么我们改写一下,在AppBaseActivity中添加如下方法,
public void startOff(final String activityName,final Intent intent) {
Class<?> clazz = null;
try {
clazz = Class.forName(activityName);
if (clazz != null) {
intent.setClass(this, clazz);
this.startActivity(intent);
}
} catch (final ClassNotFoundException e) {
return;
}
}
并且,写一个全局类ActivityNameTables
public class ActivityNameTables {
public final static String Person1Activity = "com.mytest.activity.Person1Activity";
public final static String Person2Activity = "com.mytest.activity.Person2Activity";
}
相应的,startActivity也改成如下
Intent intent = new Intent();
intent.putExtra("name","kevin");
startOff(ActivityNameTables.Person2Activity,intent);
记录日志
大多数APP都要记录日志,以便后期统计日志、分析性能、崩溃率、PV、UV、留存率、转化率等,如果自己实现,一般都会在打开Activity后的第一件事就记录下来,因为在上一步中我们有了startOff方法,我们可以,所有的Activity打开都会使用这个方法,所以我们就在这个方法中实现日志的记录:
public void startOff(final String activityName,final Intent intent) {
writePV(activityName);
Class<?> clazz = null;
try {
clazz = Class.forName(activityName);
if (clazz != null) {
intent.setClass(this, clazz);
this.startActivity(intent);
}
} catch (final ClassNotFoundException e) {
return;
}
}
private void writePV(String activityName){
......
}
BaseActivity的诞生不是一步到位,是一个不断向上抽取的过程,我们希望BaseActivity永远健壮成长!