Android編程規范不完全指南

pfmm 9年前發布 | 12K 次閱讀 Android Android開發 移動開發

參考資料:我總結的Android編程規范

1. 命名規則

1.1 類名,接口名:

以大寫開頭,如果一個類的類名由多個單詞組成,所有單詞的首字母必須大寫,單詞盡量寫全稱,不要簡寫,除非約定俗成的名字,例如:URL,RTMP,RTSP 這些廣泛使用的專有名詞,可以全部大寫,也可以首字母大寫。

例如:HttpRequest,CourseActivity

1.2 局部變量,類的成員變量,類的成員函數,函數參數:

以小寫字母開頭其他的單詞首字母大寫,變量名不建議使用下劃線分隔單詞,建議使用駝峰命名法,Android 的系統類都采用此方法。

例如:toString(),onCreateView(Bundle saveInstanceState)

1.3 靜態常量:

常量單詞全部大寫,所以單詞之間使用下劃線分隔。

例如:WHAT_EMPTY_CONTENT

1.4 控件變量的命令,控件的ID命名:

建議:xml 布局文件中的控件的id的命令與*.java的代碼文件中的空間對象的命名保持一致。

class MyActivity extends Activity {
    TextView txtUserName;
    ...
    void onCreate(Bundle saveInstanceState) {
        txtUserName = (TextView) findViewById(R.id.txtUserName);
    }
}

1.5 常用控件以及類對象命名的規范說明:

</tr> </tbody>

</tr>

</tr>

</tr>

</tr>

</tr>

</tr>

</tr>

</tr>

</tr>

</tr>

</tr>

</tr>

</tr>

</tr>

</tr>

</tr>

</tr> </tbody> </table>

1.6 資源命名:

  1. layout資源文件的命名(全部小寫,下劃線分隔):

    • activity資源文件:activity_description1_description2.xml
    • fragment資源文件:fragment_description1_description2.xml
    • listview列表項資源文件:list_item_description1_description2.xml
    • 可復用(被include)的組件資源文件:control_description1_description2.xml
    • drawable資源:controlName_description1_description2_selector.xml

      • controlName表示該資源要用在什么類型的控件上,例如:如果是按鈕的圖片切換則應該命名為button_bg_sendmessage_selector.xml
      • selector表示該資源的形式,例如還有shape等
      • </ul> </li> </ul> </li>

      • 圖片資源的命名:同上
      • 顏色值的命名:color_description以color為前綴,全部小寫,下劃線分割。
        description既可以是該顏色使用的功能描述,也可以是該顏色的英文描述,也可以是具體的顏色值,例如:
        <color name="color_white">#ffffff</color>
        <color name="color_grey_ccc">#cccccc</color>
        <color name="color_grey_ddd">#dddddd</color>
        因為grey可能有很多的等級,有時候需要不同等級的灰色,沒有那么多英文名可以區分,所以名字中可以直接使用顏色值
        <color name="color_button_pressed">#4c4c4c</color>
        根據功能定義description,表示該顏色用于按鈕按下
      • </ol>

        注:不允許出現毫無意義的命名,例如 textview1, textview2

        2. 關于字面常量

        代碼中不允許出現直接硬編碼的字面常量,如果是控件上顯示的文本,必須放在string.xml資源文件中。如果是代碼中用到的常量字符串,必須定義成public static final String類型的常量值,在代碼中使用該定義的常量值。

        這樣做的好處是以后需要修改該常量值,只需要修改一個地方。如果是硬編碼在代碼中則需要修改所有使用它的地方,而且拷貝容易出錯。

        在Activity之間傳遞參數的時候,intent.putExtra的key值也要符合命名規范,并且統一定義為靜態常量,不能直接硬編碼在代碼中,否則想要修改的時候非常麻煩。某一個Activity在被啟動的時候需要接受參數,那么這些參數的key定義就應該放在該Activity中。

        3. JSON解析

        Android中調用服務器端的接口一般返回的是JSON數據,在解析JSON的時候,無論是使用原始的手工解析方式,還是使用javabean的解析方式,解析出來的結果在使用的時候必須都進行判空處理。不允許因為服務端的json出問題,導致app在解析json的時候出現崩潰。

        4. 類成員初始化

        所有類的成員變量一定要賦初始值,不允許只定義,不賦值。

        5. Int類型常量

        函數返回的時候,如果返回的int類型的數據并不是真實的實用的數據值(例如表示寬度、高度、大小等值),僅僅代表函數執行成功、失敗、異常的狀態值,并且這些值是有限的幾個值,必須要將這些值使用靜態常量描述,或者使用枚舉類型,例如:

        int GetJsonString()

        該函數返回-1表示獲取解析JSON數據異常,返回0表示成功,返回1表示網絡連接異常,返回2表示JSON內容中的數據部分為空。

        那么在函數內部的代碼里不要直接使用這些字面值,這些字面值對于程序員來說是毫無意義的,代碼可閱讀性很差,建議做成下面的模式:

        public static final int RESULT_PARSE_JSON_EXCEPTION = -1;
        public static final int RESULT_SUCCESS = 0;
        public static final int RESULT_NETWORK_EXCEPTION = 1;
        public static final int RESULT_NO_DATA = 2;

        使用這些符號常量值代替字面值的好處是,符號常量值是由大寫的英文單詞組成,是有意義的,可以幫助程序員更好的理解函數返回值的意義,而且符號常量值對應的具體的賦值在后期也是很方便修改的。

        6. Activity 接受參數與模塊化

        如果一個Activity可能在多個地方被打開,或者一個Fragment可能在多個地方被用到。那么在設計該Activity和Fragment的時候一定要考慮低耦合,對外提供統一的參數接口,啟動Activity的過程封裝在該Activity類的靜態成員方法里。

        類似如下:

        class MyActivity extends Activity {
            ...
            public static void startActivity(Context context, Params param) {
                Intent intent = new Intent(context, MyActivity.class);
                intent.putExtra("param", param);
                startActivity(intent);
            }

        public static void startActivityForResult(Context context, Params param) {
            Intent intent = new Intent(context, MyActivity.class)
            intent.putExtra("param", param);
            startActivityForResult(intent, REQUEST_CODE);
        }
        

        }</pre>

        參數的傳遞最好是封裝在一個Model實體中,避免使用Map這種方式進行參數傳遞。建議該實體類實現為對應的Activity的靜態可序列化的內部類。

        7. Android Studio 工程目錄組織

        Android Studio 中的項目的包結構應該根據工程各個部分的功能來組織。

        8. Handler 的封裝

        每個Activity里面幾乎都會定義一個Handler內部類,但是很多Activity里面的Handler都使用了重復的消息類型,這里面是有冗余代碼的,所以應該把這些Activity都是用到的Handler類的消息部分,提取成一個公共的Handler類。

        然后在各個Activity里面使用繼承的方式,來提供該Activity特有的Handler消息類型的Handler類實現。

        另外Handler發送消息應該使用Handler類的成員函數,不應該直接使用handler.obtainMessage(xxx).sendToTarget();這種原始的發送消息的方式,這樣不利于降低耦合,這種細節應該隱藏在Handler類的里面。

        Handler的消息類型應該定義為Handler類里面的靜態常量,而該常量不應是public的,對外部不可見。也就是說使用handler對象發送消息的細節不應該暴露給外部。

        9. List 數據更新

        封裝ListView的數據更新,在handlerMessage中更新數據,避免出現java.lang.IllegalStateException問題

        10. Activity 與 Fragment 之間傳遞參數

        Activity與Fragment的數據傳遞采用interface的方式,也就是代理的方式,這樣可以降低耦合,有利于Fragment的復用:
        在你的fragment中定義一個接口:

        public interface OnDataPass {
            public void onDataPass(String data);
        }

        然后,在你的fragment中onAttach(Activity a)方法中實例化一個OnDataPass:

        OnDataPass dataPasser;

        @Override public void onAttach(Activity a) { super.onAttach(a); dataPasser = (OnDataPass) a; }</pre>

        在你的fragment中,當你想處理傳遞的數據時,只需要調用dataPasser的onDataPass方法即可:

        public void passData(String data) {
            dataPasser.onDataPass(data);
        }

        最后,在你的容器activity中實現OnDataPass接口:

        public class MyActivity extends Activity implements OnDataPass {
            ...
            @Override
            public void onDataPass(String data) {
                Log.d("LOG", "Hello " + data);
            }
        }

        11. 網絡請求數據模塊化

        一般在Activity中我們通過網絡請求服務端的接口獲得數據,這個過程一般是在一個線程中做的,獲取到數據之后,再通過Activity中的handler發送消息來通知Activity更新數據。

        該負責獲取數據的線程類,我們一般都實現為一個Activity的內部類,該類可以直接訪問Activity的成員變量,例如handler,數據列表對象等。但是這樣不利于該數據獲取線程的復用。如果另一個Activity里面也需要獲取相同的數據,那么這個功能是不能復用的。

        所以這個負責數據請求的線程類,不應該與具體的Handler和Activity聯系過于緊密。應該定義為一個靜態類,handler應該作為參數傳遞進來,而不是直接訪問外部類的成員變量。

        12. 封裝 Log 功能

        Log功能應該封裝成為自動將當前所在類的類名變成log輸出的TAG參數,發布的app最好是能循環寫日志文件到系統存儲中,并且日志文件應該使用反復覆蓋的方式重復利用。

        下面僅僅是一個不完善的例子:

        public class MyLog {
            public static final String TAG = "myapp ";
            public static void v(Object o, String message) {
                Log.v(TAG + o.getClass().getSimpleName(), message);
            }
        }

        使用方法:

        MyLog(this, "Hello Log");

        打印結果

        V/myapp MainActivity: Hello Log

        13. 版本控制

        使用自動化版本管理,自動生成版本號,使應用程序的版本與版本庫上保持一致。

        使用hg替換工程目錄下的app目錄下的build.gradle文件即可,如果AndroidManifest.xml里面也有版本號的設置,AndroidStudio還是以build.gradle為準。不應該在每次發布的時候,在AndroidStudio的工程設置里面手工修改版本號。

        14. 為程序添加全局異常捕獲

        應該為app添加全局異常捕獲,app中總會有一些我們未捕獲的異常,一旦用戶使用過程中遇到這樣的異常,程序就會崩潰,我們應該檢測該類未捕獲的異常信息,程序崩潰的時候通過寫文件日志,或者發送郵件的方式獲得異常信息,以便解決bug。

        來自:http://www.jianshu.com/p/78fa1e77a41f

         本文由用戶 pfmm 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
         轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
         本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!
類名 變量名 類名 變量名
TextView txtDescription ProgressBar progressDescription
Button btnDescription SeekBar seekBarDescription
ImageButton imgBtnDescription VideoView vvDescription
ImageView imgDescription Spinner spinDescription
RadioButton rbDescription WebView webViewDescription
EditText editDescription ListView listViewDescription
ScrollView scrollDescription GridView gridDescription
Handler descriptionHandler RatingBar ratingBarDescription
PullToRefreshListView pullRefreshViewDescription Adapter descriptionAdapter
Fragment descriptionFragment Activity descriptionActivity
List<T> descriptionList Map<> mapDescription
SlidingMenu slidMenuDescription ViewPager viewPagerDescription
CheckBox chBoxDescription View viewDescription
RadioGroup rgDescription ExpandableListView expDescription
FrameLayout frameLayDescription SharedPreferences spDescription
LinearLayout lineLayDescription RelativeLayout relativeLayDescription
startActivityForResult(requestCode) REQUEST_CODE_DESCRIPTION msg.what WHAT_DESCRIPTION
  • sesese色