您的位置:首页 > 其它

记录下对项目进行重构的过程

2016-07-01 16:29 211 查看
最近因为研究了Retrofit+RxJava+MVP,感觉这种组合相当好,再看看自己之前写的代码,可维护性真的太差了。

由于公司项目使用的是WebService+xml,所以我写了个Demo让WebService+xml也能使用Retrofit+Rx+MVP,花费了比较多的时间,主要是对xml解析那块,需要使用simplexml来解析,但情况又不完全符合。但后来想想,如果把项目真的完全改成这种模式,那付出的代价太大了。

由于项目是已经上线的,对项目进行重构,必须要保证能够对之前的版本兼容。

后来我仔细思考,Retrofit也属于网络框架,我们项目中也为WebService封装了自己的网络请求框架,所以,如果把Retrofit强行移植到项目中,并不一定能提高效率,反而增加重构的工作量。

打算对项目进行重构,从以下几个步骤进行。

· 1 全面压缩apk大小

声明一下,这应该不算是重构的内容,但也是我在这个目标中给自己规定的一定要完成的任务。

在网上找了许多教程,主要是参考这几个网站

如何将apk大小减少6M的

APK瘦身实践

使用lint检查删除冗余代码和资源

ctrl+shift+alt+I 输入unused会弹出很多提示,

我主要是用unused assignment和unused resource。

使用unused resource的时候要谨慎, 防止误删有用的资源,因为有时候第三方包需要使用的资源,这里是检查不到的,比如极光推送,需要一个名字为jpush_notification_icon.png的文件,这些细节注意下即可。

其次就是删掉so包,只保留一个armeabi,关于这一步,如果有问题,也可参考我的另一篇博客 http://blog.csdn.net/fancy_xty/article/details/51801510

做完这些操作,我的apk成功减小了6M

· 2 对Realm数据库进行合并

刚开始使用Realm数据库的时候,对它并不是特别了解,建了许多个数据库,当时其实也知道这样不太好,但想着能实现功能就没管那么多了。

但后来项目上线以后,经理总是要求功能改这改那,有时候就不得不对数据库结构进行修改,Realm数据库结构发生变化时是需要使用Migration的,需要自己定义升级操作。但是我当时建的数据库太多,导致升级时迁移困难。

所以我就想到了将Realm数据库来一个大合并,全都合并到一个数据库中去。

但这也不是一件简单的事,首先也是最重要的就是要保证对以前版本的兼容性。之前我使用的Realm数据库是0.89.1的,在合并数据库的过程中遇到了许多错误,后来尝试升级了1.0的版本,就成功将数据库合并了。

现在只剩下一个数据库,每次更改数据库结构,我只需要编写一个Migration就可以万事大吉了。不用担心其他各种各种问题。

· 3 使用ButterKnife8.1.0 替代之前的7.0.1的版本

ButterKnife算是有名的组件注入框架了,之前一直使用7.0.1的版本,但后来在网上看到资料,7.0.1是在运行时注入的,有点儿影响效率,新出的8.1.0的版本是在编译时注入的,不会对运行造成任何影响,我就果断升级8.1.0啦。

不过8.1.0有部分语法和之前不太一样了,所以代码里面都要改,我没有找到一键把工程中所有的Bind全都替换成BindView的方法,而且这样应该也不安全,容易出现未知错误。所以只好一个文件一个文件替换了。

· 4 创建新的BaseActivity(多个)

之前项目中也写了一BaseActivity,但完成的功能是在太少了。

编写新的BaseActivity,BaseFragment等等也是为了适应即将逐步嵌入的MVP框架和RxJava。

这个就不多说了,主要就是把公共的View提取到BaseActivity中,还有提供一些公共的方法。在BaseActivity中完成页面打点,ButterKnife的绑定之类的操作。有了一系列的BaseView之后,可以大大简化Acitivity中的操作。

我认为这个是非常必要的,BaseView也需要在项目编写过程中不断增加公共内容,不断地完善。

BaseActivity中可以结合IBase,BasePresenter完成view的attach、dettach,弱引用关联,unSubscribe等。这是非常必要的,使用MVP框架,如果不这样做,非常容易引起内存泄漏。

贴上我的BaseActivity在这方面的处理,只贴核心代码。

public abstract class BaseActivityNoLayout<V,T extends BasePresenter<V>> extends AppCompatActivity implements IBase {
protected T mPresenter;
protected boolean nowRequest;

@Override
public void setContentView(@LayoutRes int layoutResID) {
super.setContentView(layoutResID);
ButterKnife.bind(this);
}

@Override
protected void onDestroy() {
super.onDestroy();
if(mPresenter != null)
mPresenter.dettachView();
}

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPresenter = createPresenter();
}

protected abstract T createPresenter();

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

@Override
public boolean hasNet() {
return NetUtil.hasNet(getMApplicationContext());
}
}


还有BasePresenter进行弱引用关联,即使你忘记dettach,等网络请求结束后,系统也会完成回收功能。

/**
* Created by fancy on 2016/6/22.
*/
public abstract class BasePresenter<T> {
String TAG = "BasePresenter";

//view接口类型的弱引用
protected Reference<T> mViewRef;

public void attachView(T view) {
Log.d(TAG, "attachView: "+mViewRef);
mViewRef = new WeakReference<T>(view);
Log.d(TAG, "attachView: "+mViewRef);
}

protected T getView() {
return mViewRef.get();
}

public boolean isViewAttached() {
return mViewRef != null && mViewRef.get() != null;
}

public void dettachView() {
if (mViewRef != null) {
mViewRef.clear();
mViewRef = null;
}
}
}


· 5 将MVP和Rx逐步嵌入项目

在我的项目中原本是使用异步任务执行网络请求的,这就导致了网络请求需要排队执行,非常地影响效率,网速比较慢的时候就更加坑爹了,慢到想死。

所以想使用RxJava来替代异步任务,不过一口是吃不成胖子的,如果想一次性全都改了,容易出错。

之前我新建了项目打算重定项目接口,包都分好了,但很快发现这样不现实,第一项目已经上线,还在不断维护,有时要开发新功能,很难保证同步,而且时不时又要回到原来的项目中去,来回切换不仅心累还耗时间。

后来我决定使用逐步替换的方式。

从用户最先接触到的功能,最重要的功能改起,一步一步使用MVP和Rx代替。当我成功替换一个功能之后,很快我就看到了效果,请求到结果的时间大大减少了,一条线变成了多条线能不快多了吗,现在这一步还没有完全完成,还只替换了绝大部分。

使用这种模式还有一个非常大的好处就是程序解耦,降低程序耦合性,方便程序维护,真想感叹一句,MVP和总是要求改改改的经理更配哦~

有了RxJava之前我想到的网络请求优化方案都能so的一下实现了。

最后,对文章中提到的内容有任何疑问,欢迎加群讨论:283272067
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息