安卓维护项目小结以及注意事项[个人总结]
前言
工作的几家公司都是维护迭代旧项目,我个人做了一些维护总结,目前准备学习后端,所以留一个文章以后再来复习一些经验,如果写的不好请见谅,欢迎提出改进意见
新人入职拿到项目的源代码一开始都不知道要干什么,
相信不止我一个人这样吧,下面我来讲一下几个情景出现的问题
一些常见问题(坑人)
这也是我遇到过最多的情况,同时也是属于最坑的情况,通常存在几个问题
- 项目有复数的网络请求框架,包含ui通讯逻辑
- 项目有过多的重复复制粘贴的代码或者是导入了无用的库
- 项目类名起名莫名其妙,不规范
- 项目没有相关文档
- 项目没有产品原型图
这些问题很常见,下面进入正题,一些经验之谈
快速了解页面组成
首先第一步查找app入口页面,这个非常简单直接去清单文件找
<activity
android:name="入口acitvity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
找这个相关的intent-filter就可以了,但是这只是开个头而已,其实工作还是没有什么实际性进展,目前要知道的是在用的是哪一个页面名字是什么,如果有开发文档可以对照开发文档查看对比页面但是在没有任何文档下,如果遇见命名不规范的项目,清单文件也是不好找的.我这里是这样用的,去清单文件查找有没有自定义的app域
<application
android:name=".app.MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:supportsRtl="true"
android:largeHeap="true"
android:theme="@style/AppTheme"
>
存在name标签就是有,然后ctrl点击MyApplication(名字为自定义的名字),直接跳转到该类(如果项目没有该标签,请自行到项目目录新建一个继承Application的类,然后在清单文件这里做好配置),并实现接口ActivityLifecycleCallbacks,该接口会回调项目中所有的acitvity生命周期的流程,点击这里查看关于ActivityLifecycleCallbacks的更多用法(转载侵删)
public class TestApplication extends Application implements Application.ActivityLifecycleCallbacks
{
@Override
public void onCreate() {
super.onCreate();
//注册回调,一定要写这一句
registerActivityLifecycleCallbacks(this);
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
}
Activity中的onStrat(),onResume();onCreate()对应回调onActivityStrat();onActivityResumed();onAcitivityCreate(); Activity启动的三个会被回调的方法,在任意一个中写入,建议最好在onAcitivityCreate()里,该回调只会在启动某个Activity调用一次(销毁页面前)
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState)
{
Log.e("现在是",activity.getLocalClassName());
}
最后部署(真机或模拟器),启动到出现bug的页面,发现logcat出现如下内容,并且附带包名全路径
到清单文件利用Crtl+F查找
对于了解整个目录结构和页面能够快速的眼熟,也可以分辨哪些是activity哪些是fragment(有的页面跳转是替换内容为一个新的fragment),利用这个就不难分辨
快速定位项目网络框架
网络框架组合方式
网络请求是延时操作,请求结束后需要将结果回调至ui线程更新ui,其实都是大同小异,下面列举一下常见的几种
- httpconnection+handler(这种一般在元老级项目里面存在)
- okhttp+handler或eventbus (最常见)
- retrofit+eventbus或rxjava或handler(最近流行的)
- okgo或xUtils (快速开发使用的,方便省事,更新ui自己回调封装好了 写着爽后期难维护)
关于eventbus使用(侵删)
关于retrofit使用(侵删)
快速判断使用的哪种框架,前往moudle下的gradle文件查看依赖和libs文件夹里的jar包
可以快速确定项目所使用的网络框架,不用一开始就摸不着头脑
快速定位某类/某变量 or 常量/某资源文件
编译器界面双击shift启用全局搜索,输入关键字,会将全局对应的关键字的资源检索出来,在资源文件过多的情况下知道名字可以立即检索,这个其实不说相信大家都在用的
快速定位Fragment,以及展示的是哪个Fragment界面
定位了Activity后,不难分辨出fragment是再哪一个页面,下面将一下三种情况的定位某Activity绑定的Fragment情况,如果不知道项目属于哪种情况,可以直接三种方法都使用
fragment属于静态添加
再回到自定义的Application,在回调的onActivityCreated()方法里:
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log.e("目标activity",activity.getClass().getSimpleName());
if (activity instanceof MainActivity)
{
activity.getFragmentManager();
}
}
如果activity继承的父类或者顶级父类是 AppCompatActivity,改为
(目前的安卓项目大部分都使用的support包下的AppCompatActivity做为父类)
activity.getSupportFragmentManager();
利用方法
fragment如果是静态加载的话下面的代码就可以定位(也就是直接添加至视图容器)
if (activity instanceof MainActivity)
{
FragmentManager fragmentManager =((MainActivity) activity).getSupportFragmentManager();
List<Fragment> fragmentList = fragmentManager.getFragments();
if (fragmentList!=null&&fragmentList.size()>0)
{
for (Fragment fragment:fragmentList)
{
Log.e("挂载的fragment",fragment.getClass().getSimpleName());
}
}
}
Fragment属于动态添加或者是使用了viewpager
第二种情况使用了tab来切换,也就是tab框架+viewpager形势,这种一般都是定义了一个adapter继承了FragmentPageAdapter,善用全局搜索
以上如果fragment的适配器命名规范,就不难找到对应页面的的适配器,顺腾摸瓜就能找到绑定的相关fragment,如果命名不规范像这种
直接前往FragmentPageAdapter类,Crtl键点击快速检索可以看到是哪些类继承了,点击进入类,在Crtl键点击类名可以看到是哪个Activity引用了,到目标Activity说明就是这个适配器,可以顺腾摸瓜找到所有绑定的Fragment
所有的Fragment存在同一个父类或者多个父类
有的项目比较用心对所有的Fragment进行类父类重写,建立了新的Fragment基类
让所有的Fragment都继承于它,如果是这种定位Fragment是最简单的.先观察所有Fragment发现它们都有一个相同的自定义的父类
父类肯定也是继承了Fragment为父类,所有我们可以在这个类中重写onAttch()方法,这个方法在Fragment和Activity绑定调用
@Override
public void onAttach(Context context) {
super.onAttach(context);
Activity activity = getActivity();
if (activity!=null)
{
if (activity instanceof MainActivity)
{
Log.e("属于MianActivity的fragment",this.getClass().getSimpleName());
}
}
}
运行就可以在logcat看到对应的Fragment了
到此为止项目的结构基本就能熟悉了,可以开始着手调试修复bug
结束
这里主要简单说一下如何避免出现上面所描述的项目出现的问题(自己产生)
- 代码风格可以不一样但是利用的第三方工具框架(网络框架之类的要向前一个看齐),这也是对后面的人负责
- 对于重复的逻辑建议封装降低代码耦合度
- 不要老想着重构,一般不会给太多时间
如果项目bug太多而且还是遗留下来的,上个程序员才离职,又招的你那种,建议短时间跳槽.垃圾代码就像屎一样后来的人维护会把屎越堆越高最后变成屎山,越爬越恶心