android开发的同学,相信都遇到过在写代码的过程中,需要花费很多时间去做一些重复的劳动,比如下面这些:
上面这些提到的没有技术含量得“体力活”,可能会占据了我们开发不少的时间,一方面浪费时间、另一方面无法专心开发具体业务需求,我下面总结了一下消灭这些体力活的方法
估计大家对DI应该有所了解,因为在android开发里面,这是最浪费体力活的工作,前不久,我所负责的项目android版本需要新增一个新的模块,新的模块流程复杂、交互比较多,开工之前预计至少要3周时间开发,我决定尝试使用一个DI库 Butterknife来开发,配合android studio插件使用,自从用起来后,写代码的心情就一个字:很爽!并且最终整个模块提前一周时间基本功能都写出来。
一些常见的android DI库包括
上面DI库用起来都是大同小异,而且性能都很好,因为它们基本都是编译时生成缓存来提供运行时使用,而不是运行时反射来调用。
Android Annotation看上去功能最强大,支持大量的注解,除了view,event,还包括各种你可以想到的注入,比如service、resource、多线程、甚至还包括http服务注入! 看下面官网的例子截图,使用Android Annotation后,代码简洁得异常残暴!!!
不过最终我们还是选择了ButterKnife,它比较轻量级,如果直接就上AA,担心步子迈得太大,大家不(rong)太(yi)习(che)惯(dan),不过其实最主要原因还是因为Butterknife提供了IDE插件,其实我们的android项目之前也有一套自己写的简单的ViewInject的注解,但是没有插件支持,所以插件支持很重要,它能真正帮助我们解放体力活。 下面是ButterKnife的使用介绍动画
另外插件还可以配置生成view的私有变量的前缀,比如统一前面加“m”前缀
我前面一开始所提到的创建一个列表时候,所需要创建一大堆文件,而且这些文件零零散散分布在各个文件夹,这也是一件很繁琐的体力活。 我使用了一个完全没有技术含量的方法来做这些“体力活”,我在项目里面创建了一个工具,然后通过自定义模块来生成需要的文件
首先,创建模版文件
我新建立了一个module叫“templateutil”,里面包括需要创建的模版template目录,可以将通用的activity、fragment、layout放在里面
创建了两个给gradle执行任务的class
分别是CreateListActivity用来创建相关一整套的class和layout、和CreateModel用来创建model层相关class
public class CreateListActivity {
public static void main(String[] args) {
System.out.println("===== Create listactivity start =====");
String model = args[0];
System.out.println("model:" + args[0]);
// 获取当前module path
String currProjectPath = System.getProperty("user.dir");
// 模版path
String tmpPath = currProjectPath + "/template/listactivity";
// app src path
String appPath = currProjectPath + "/../app/src/main/java/com/netease/mail/oneduobaohydrid/";
// resource path
String resPath = currProjectPath + "/../app/src/main/res/layout/";
/** 各个文件路径定义开始 **/
String tmpActivityFile = tmpPath + "/Activity.java";
String activityFile = appPath + "activity/" + Util.upperCaseModel(model) + "Activity.java";
String tmpAdapterFile = tmpPath + "/Adapter.java";
String adapterFile = appPath + "adapter/" + Util.upperCaseModel(model) + "Adapter.java";
String tmpFragmentFile = tmpPath + "/Fragment.java";
String fragmentFile = appPath + "fragment/" + Util.upperCaseModel(model) + "Fragment.java";
String tmpActivityXml = tmpPath + "/activity.xml";
String activityXml = resPath + "activity_" + model + ".xml";
String tmpFragmentXml = tmpPath + "/fragment.xml";
String fragmentXml = resPath + "fragment_" + model + ".xml";
String tmpItemXml = tmpPath + "/layout_item.xml";
String itemXml = resPath + "layout_item_" + model + ".xml";
/** 各个文件路径定义结束 **/
System.out.println("tmpPath:" + tmpPath);
System.out.println("appPath:" + appPath);
/** 下面开始读取、替换、保存到目标 **/
Util.buildFile(tmpActivityFile, activityFile, model);
Util.buildFile(tmpAdapterFile, adapterFile, model);
Util.buildFile(tmpFragmentFile, fragmentFile, model);
Util.buildFile(tmpActivityXml, activityXml, model);
Util.buildFile(tmpFragmentXml, fragmentXml, model);
Util.buildFile(tmpItemXml, itemXml, model);
System.out.println("===== Create listactivity finish =====");
}
}
public class CreateModel {
public static void main(String[] args) {
System.out.println("===== Create model start =====");
String model = args[0];
System.out.println("model:" + args[0]);
String currProjectPath = System.getProperty("user.dir");
String tmpPath = currProjectPath + "/template/model";
String modelPath = currProjectPath + "/../model/src/main/java/com/netease/mail/oneduobaohydrid/model/" + model.toLowerCase();
System.out.println("tmpPath:" + tmpPath);
System.out.println("modelPath:" + modelPath);
File file =new File(modelPath);
if (!file.exists() && !file.isDirectory()){
file.mkdir();
Util.buildFiles(tmpPath, model, modelPath);
} else {
System.out.println("!!!!!Model目录已存在" + modelPath + "");
}
System.out.println("===== Create model finish =====");
}
}
两个task分别创建ListActivity任务和创建Model任务
// gradle createModel -Pmodel=wishlist
task createModel (type: JavaExec, dependsOn: classes) {
if(project.hasProperty('model')){
args(model)
}
main = 'com.templateutil.CreateModel'
classpath = sourceSets.main.runtimeClasspath
}
// gradle createListActivity -Pmodel=wishlist
task createListActivity (type: JavaExec, dependsOn: classes) {
if(project.hasProperty('model')){
args(model)
}
main = 'com.templateutil.CreateListActivity'
classpath = sourceSets.main.runtimeClasspath
}
harry$ gradle createListActivity -Pmodel=wishlist
现在一些大型的android项目,里面可能存在多个module,依赖很多库,每次需要run或者debug时候,需要一两分钟时间等待task run完,才能调试,下面有三个方法缩短这个build时间
爆栈里的这个修改gradle配置方法经过实践证明确实可以减少一点build时间,在我的项目里面大概可以减少10-20s
来自facebook的buck,据说可以将build时间缩短到十分之一,WOW!不过我没有用过,因为看介绍说,它放弃了gradle的build system,并且需要修改大量的代码,所以我们放弃用它
当看到LayoutCast README的第一行说明,我忍不住想跟作者握个抓
Android SDK sucks. It's so slow to build and run which waste me a lot of time every day.
LayoutCast最大的好处是,不需要修改太多的代码,速度方面在介绍中有数据对比,据称比buck还要快,我试过放入我们的项目,可能是因为我们的项目结构比较复杂module比较多,一直没有运行成功,不过我新建project测试是可以用的
有个很好用的调试真机webview的chrome插件,通过adb连接直接调试真机,而不需要chrome模拟移动设备
最后这个是一个小工具,使用adb命令可以快速进行wifi代理的设置和清除,亲测有效!
网易云新用户大礼包:https://www.163yun.com/gift
本文来自网易实践者社区,经作者陈志凌授权发布。