Skip to content

His Hv Code Style

AlanDan edited this page Feb 9, 2017 · 6 revisions

#Android编码规范 ###之前编写的文档,保存这里。2017/2/10

(... - Android ... : **戴鹏飞)**2014-10-17


#一 :JAVA

1:#变量篇

######应用场景: 非纯数据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);}
3)模糊概念:
	没有严格的定死的界限,每个人都有自己的理解方式,宗旨是让他	人容易理解。
	透过这点,比如你可以把一个事实上是一个ImageView的控件叫做	mBackButton,只	
	因为它是可点击并且是返回控件。

2:#代码篇

*** 几条建议 :***

#####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的内部私有类会有个外部类的强引用,如图

handleErro

  想象一下,当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:

eclipse no warning

######5)多写注释

  如果一个代码块、方法的虽然保持了单业务,即已经达到了抽象的目的,是从大业务上提出来的,比如上面的findViews,setViews等,假如其中的代码量很大,小逻辑很多,请分段注释。

  下面是我曾经写过的示例 :

annotation show

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...

Clone this wiki locally