-
Notifications
You must be signed in to change notification settings - Fork 0
His Hv Code Style
#Android编码规范
###之前编写的文档,保存这里。2017/2/10
(... - Android ... : **戴鹏飞)**2014-10-17
#一 :JAVA
######应用场景: 非纯数据model 类, model类可以不遵循(内部类也可以) #####规范: 驼峰- tF/Tf(注:下面表格中标识tF/Tf均为驼峰的意思)
word- W (注:同上)
######1.1: Prefix-前缀[m,s,is,mIs]
catogry/scope | local | class | class sample |
---|---|---|---|
\ | tF | mTf | mSample |
Static | \ | sTf | sSample |
Final | tF | mTf | mSample |
StaticFinal | \ | W_W_W | THE_SAMPLE |
Boolean (Special) | isTf | mIsTf | mIsSample |
######1.2:Android控件 suffix-后缀
#####规则: ######1)区别于其他变量,编码人员应当至少标明(让人容易理解为)该变量为一个View: ( option-可选 : 如果本身控件名短的可以用全部后缀 )
规格:[mTfView]
示例:{mTitleTextView, mBackButton, mLabelView, mProgressBar};
######2)比如我们有个回退按钮,定义的layoutId为@+id/backButton 变量名与View Id 关联: 示例:
{mBackButton = findViewById(R.id.backButton);}
没有严格的定死的界限,每个人都有自己的理解方式,宗旨是让他 人容易理解。
透过这点,比如你可以把一个事实上是一个ImageView的控件叫做 mBackButton,只
因为它是可点击并且是返回控件。
*** 几条建议 :***
#####1)Activity中一般情况下避免创建public函数:
我们知道,Android OS本身并不提供启动后的Activity的引用。一定程度上说明了系统人员并不想让我们直接操作Activity变量,一方面是因为Activity本身是有public方法的,系统当然不会让我么随便调用,这样是危险的。另一方面我们本身也应该用这样的思想去构建符合安卓的Activity subclass.
#####2)Activity中避免一个函数中有太多的不同业务在一起 典型便是onCreate方法中很多业务都放在里面,前后无序,长时间的维护、修补造成的及格过便是,一眼看去不想再看第二眼,这样对我们阅读代码是痛苦的,重构时间成本很高,费时费力,因为逻辑不够清晰、条理。导致修改越来越容易产生bug。推荐大家经常翻看一本叫做**《重构》**的书,个人的心得是没事翻一翻,不需要通读,培养自己对坏代码的嗅觉。简单的小示例:
//find views
mBackButton = findViewById(R.id.backButton);
// set listener
mBackButton.setOnClickListener(
new Button.OnClickListener(){
public void onClick(View view){
//…….
}
});
… … …
之间还穿插着类似...
mXX = getIntent().getString…
…
loadData().;
…
这样的代码全部写到onCreate域中无疑是糟糕的,如果改Activity拥有大量的View,和前期对view的适配、数据配置呢。
我们应该把他们提出来:
/** Called when this activity is first created. */
@Override
onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getDataFromIntent();//从Intent中获取数据
initialize();//初始化
// 请求数据,此方法可以根据情况写到onRsume中
loadData();
}
private void initialize(){
// find View by id。
findViews();
/* set listeners , set others,比如里面有
* setListView,setBackButton等等*/
setViews();
}
上面只是一个小示例,抛砖引玉,希望大家有足够的嗅觉,培养自己提取 代码的思想意识.
#####3)让别人更懂你
什么样的代码才算好代码,在我看来,我们主要的工作是告诉硬件怎么去按照一定的程式去运行、工作,但是为了更好的维护既有的代码,我们更主要的是要告诉他人,甚至未来的自己:这段代码在讲什么,更容易的理解,一定是命名上的,打个小比方:有一个按钮开关代表了打开和关闭一个功能,我们根据不同的状态来判断打开和关闭,由于只有两个状态,一般情况下我们用boolean来标识,也即是true和false,代表打开和关闭,基于这点 ,我们一般会这样写。
setFunctionA(boolean is);
但是这样仍然不够直观,想象一下当业务复杂到诸多地方用到这个方法的时候,前一个代码处还在使用setFunctionA(true),后面没几行就要false,因为业务是这样。而且非常频繁,回不看花眼,看晕了,逻辑一旦复杂就会这样,这个时候我们可以换个字眼儿,提高阅读效果,比如新添加两个方法来代替之前的使用:
private void openFunctionA(){
setFunctionA(true);
}
AND
private void closeFunctionA(){
setFunctionA(false);
}
注:这样看来虽然代码多了,但是更清晰,不需要频繁的传入参数 true 和 false,这只是个小示例,抛砖引玉。
######4)保持类的干净,整洁!
我个人有些代码洁癖,喜欢做架构,喜欢写漂亮的代码,每个人都有自己的专 长,所以我很喜欢保持类的干净,IDE诸如eclipse,idea等通常会给我们很多lint提示,如Eclipse的编辑右边纵向栏会有红、黄、蓝通常这三种警告色,分别代表代码编辑错误、警告、TODO:之类的。我们都会注意编辑错误,因为必须注意,否则编译不通过,通常会吧警告认为忽略掉。在这里我想告诉大家,**请勿忽略任何警告!**如果有,则需先查看,再分析,然后选择是否禁用或者修复。
1) 可以改善代码的阅读效率,比如很多unused变量会导致我们需要花更多的时间成本在阅读代码过程中,去过滤这样的信息,
2)一些隐性的bug会因此产生,而且这类型的bug一旦产生,一般都是很难排查的。除非有过相关的bug修复经验。
这里我可以分享一个真实的经历,曾经我看到在新的ADT更新后,我的某个Activity中出现了黄色警告,点击提示:“This Handler class should be static or leaks might occur ”,这句话警告了我,私有内部类handler,一定情况下可以造成Activity的泄露,通过google我发现了解决方案。产生的原因。这在早期的Android版本的示例中是bug。这里我分享下原因和改进方案。
1:Java的内部私有类会有个外部类的强引用,如图
想象一下,当Activity调用finish后,外部因为如请求网络(异步线程)发送了过来的请求,通过handleMessage进行请求,通过情况下message需要处理a的时间,那至少在a时段内,activity不会被GC掉。如果handle message中进行了一个Timer呢?想象下...
2) 解决思路
按照提示使用static内部类,这样就不会有强引用了,以为static相当于外部类,因此我们需要将activity的引用传入到handle中,并且用个WeakReference包装。代码:
private static MainHandler extends Handler {
private WeakReference<XxxActivity> mActivity;
public MainHandler(XxxActivity act){
this.mActivity =
new WeakReference<XxxActivity>(act);
}
public void handleMessage(Message msg){
final XxxActivity act = mActivity.get();
//这里是关键
if(act == null){
//act 为空说明当前activity已经释放,移除所有消息
this.removeCallbacksAndMessages(null);
return;
}
switch(msg.what){
case A_B_C:
act.handleAbc();
break;
…
…
}
}
}
最后,请尽可能保持类干净,like:
######5)多写注释
如果一个代码块、方法的虽然保持了单业务,即已经达到了抽象的目的,是从大业务上提出来的,比如上面的findViews,setViews等,假如其中的代码量很大,小逻辑很多,请分段注释。
下面是我曾经写过的示例 :
Java总结:为了更健康,健壮,漂亮的代码,请大家开始良好的变成习惯,有一个好的出发点就是:想好了再去写,尽可能想到更多的扩展空间。
##二:RES
###文件名命名格式规范
####说明 :
prefix-前缀
scene-场景
subscene-进一步的场景(option可选)
name-名称
suffix-后缀
####策略:
prifix_scene_subscene_name_suffix
如:
MainActivity中titleBar上的backButton的点击状态图selector,我们会在res/drawable/下创建一个命名为
selector_main_activity_title_bar_back_button.xml
或者精简下,如果你觉得能够说清楚
selector_main_title_back_button.xml
其中:
prefix == selector (资源文件类型)
scene == main_activity/main (场景一)
subscene == title_bar/title (下一级场景)
name == back (名称)
suffix == button (控件类型)
######1: res/drawable
说明 | Prefix |
---|---|
状态选择(点击状态改变) | selector |
图形(如渐变色等) | shape |
png,用作image的src | img |
icon(任何图标) | icon |
任何background | bg |
######2: res/layout
说明 | Prefix |
---|---|
activity | ac |
fragment | fr |
自定义view | view |
专门用来include的layout | include |
(list/grid) item | item |
######3: res/others
说明 | Prefix |
---|---|
attr | attr |
dimen | dimen |
anim | anim |
string | string |
raw | raw |
to be continue...