【Android 應用開發】 Android 相關代碼規範 更新中 …

分類:編程 時間:2017-02-15

.


簡介 : android 常用的代碼結構, 包括包的規範, 測試用例規範, 數據庫模塊常用編寫規範;

參考 : 之前寫的一篇博客 【Android 應用開發】 Application 使用分析 ;

-- Application 分析 : Application 概念, 聲明周期, 組件間傳遞數據作用, 數據緩存作用;

-- 源碼分析 : 分析 Application 結構接口源碼;

-- 使用示例 : 自定義 Application 註冊, 保存崩潰日誌到文件, 監聽Activity聲明周期;




一. 包結構規範



1. 基本包, 業務包, 測試包


包基礎結構 :

-- base 包 : 應用中常用的公共包 和 類放在該包中, 例如 工具類, SQLiteOpenHelper, 配置類, Application, 各種類的基類 等;

-- business 包 : 應用中的實際業務包, 這個包存放 與 app 業務相關的具體實現的類 和 包;

-- test 包 : 用於存放單元測試 和 測試用例相關的包;


示例 :




2. 根據類型將 Java 類 分入不同包中


UI 相關 :

-- activity : 存放 Activity 相關的包;

-- fragment : 存放 Fragment 相關類;

-- widget : 存放自定義組件相關類;


適配器相關 :

-- adapter : 各種適配器, 尤其是 BaseAdapter 子類;


Java Bean相關 : 下面的兩種包名經常存放 JavaBean 對象;

-- bean :

-- domain :


工具類相關 :

-- utils : 存放工具類;


監聽器相關 :

-- listener : 存放各種監聽器, 如按鈕點擊監聽器等等;


數據庫相關 :

-- sqlite : 存放數據庫相關的包;


業務相關 :

-- engine : 存放業務邏輯相關類;



二. Application 代碼規範


1. Application 單例規範


單例屬性 : Application 本身就是單例模式, 在整個應用中, 只存在一個 Application 對象;


實現 Application 單例 :

-- 定義 Application 類型對象 : 在 自定義的 Application 中定義一個 Application 類型的函數;

private static QIApplication INSTANCE;

-- 定義共有構造方法 :

	/**
	 * 構造方法構造 Application
	 */
	public QIApplication() {
		INSTANCE = this;
	}

-- 公共, 靜態方法獲取對象 : 在任何類中, 都可以調用該方法, 獲取 Application 上下文對象;

	/**
	 * 獲取 Application 使用該函數可以在任意位置獲取 Application 中的數據
	 * @return
	 */
	public static QIApplication getInstance() {
		return INSTANCE;
	}


2. Application 用於組件間數據傳遞 和 數據緩存


【Android 應用開發】 Application 使用分析 博客中有這方面的講解;

Application 組件間數據傳遞 , Application 數據緩存;



3. Application 常用框架


代碼示例 :

public class MyApplication extends Application {

	private static MyApplication INSTANCE;
	
	/** 用於數據傳遞的 Map 集合 */
	private Map<String, Object> transferMap;
	/** 用於緩存數據的 Map 集合 */
	private Map<String, Object> cacheMap; 
	
	/**
	 * 構造方法構造 Application
	 */
	private MyApplication() {
		INSTANCE = this;
	}
	
	/**
	 * 獲取 Application 使用該函數可以在任意位置獲取 Application 中的數據
	 * @return
	 */
	public static MyApplication getInstance() {
		return INSTANCE;
	}
	
	@Override
	public void onCreate() {	
		super.onCreate();
		// 初始化用於數據傳遞的 Map 集合
		transferMap = new HashMap<String, Object>();
		// 初始化用於數據緩存的 Map 集合
		cacheMap = new HashMap<String, Object>();
	}
	
	/**
	 * 獲取數據傳遞 Map 集合
	 * @return
	 * 		數據傳遞 Map 集合
	 */
	public Map<String, Object> getTransferMap() {
		return transferMap;
	}
	
	/**
	 * 向 transferMap 集合中添加數據元素
	 */
	public void putTransferMapElement(String key, Object object) {
		transferMap.put(key, object);
	}
	
	public Object getTransferMapElement(String key) {
		return transferMap.get(key);
	}
	
	/**
	 * 向 transferMap 數據中移除對應的數據元素
	 */
	public void removeTransferMapElement(String key) {
		transferMap.remove(key);
	}

	/**
	 * 獲取數據緩存 Map 集合
	 * @return
	 * 		數據緩存 Map 集合
	 */
	public Map<String, Object> getCacheMap() {
		return cacheMap;
	}
	
}




三. 數據庫模塊代碼常用結構



1. SQLiteOpenHelper 類



(1) 命令 版本號


類命名 : 一般命令為 XXOpenHelper, 例如 DBOpenHelper;

版本號 : 在類中定義一個常量, 用於保存版本號;

private static final int database_version = 1;

(2) 單例模式


單例 : SQLiteOpenHelper 類, 在應用中只保存一個對象即可;

-- 私有, 靜態化本類成員變量 : 例如該類類名為 DBOpenHelper, 那麽定義一個 DBOpenHelper 的成員變量, 註意將改變量設置成靜態變量;

private static DbOpenHelper instance;

-- 私有化構造函數 : 將構造函數設置為私有函數;

	private DbOpenHelper(Context context) {
		super(context, getUserDatabaseName(), null, DATABASE_VERSION);
	}

-- 共有, 靜態 方法獲取成員變量 : 使用懶漢模式, 如果 本類類型成員變量 為null, 就調用私有的靜態構造方法, 如果不為null, 就直接返回 本類類型靜態變量;

	public static DbOpenHelper getInstance(Context context) {
		if (instance == null) {
			instance = new DbOpenHelper(context.getApplicationContext());
		}
		return instance;
	}

(3) SQL 語句字段名維護


字段名使用 :

-- SQLiteOpenHelper 中的字段 : 建立數據庫需要字段名稱;

-- JavaBean 中的字段 : 在代碼中經常用到字段名稱, 一般規律是 在JavaBean 中的變量名 與 數據庫中字段名相同, 字段名在 JavaBean 中需要使用, 用於從 Cursor 中獲取對象;

-- Dao 中的字段 : 在插入數據時, 也許要字段名稱;


維護字段名稱常量 : 個人認為字段名稱常量維護在 JavaBean 中最好, 這樣就可以將所有的字段名都限制在 JavaBean 類中, 其它位置不用關心字段名稱;



(4) SQLiteOpenHelper 代碼示例


/**
 * Copyright (C) 2013-2014 EaseMob Technologies. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.easemob.chatuidemo.db;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import com.easemob.applib.controller.HXSDKHelper;

public class DbOpenHelper extends SQLiteOpenHelper{

	private static final int DATABASE_VERSION = 1;
	private static DbOpenHelper instance;

	private static final String USERNAME_TABLE_CREATE = "CREATE TABLE "
			+ UserDao.TABLE_NAME + " ("
			+ UserDao.COLUMN_NAME_NICK +" TEXT, "
			+ UserDao.COLUMN_NAME_ID + " TEXT PRIMARY KEY);";
	
	private static final String INIVTE_message_TABLE_CREATE = "CREATE TABLE "
			+ InviteMessgeDao.TABLE_NAME + " ("
			+ InviteMessgeDao.COLUMN_NAME_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
			+ InviteMessgeDao.COLUMN_NAME_FROM + " TEXT, "
			+ InviteMessgeDao.COLUMN_NAME_GROUP_ID + " TEXT, "
			+ InviteMessgeDao.COLUMN_NAME_GROUP_Name + " TEXT, "
			+ InviteMessgeDao.COLUMN_NAME_REASON + " TEXT, "
			+ InviteMessgeDao.COLUMN_NAME_STATUS + " INTEGER, "
			+ InviteMessgeDao.COLUMN_NAME_ISINVITEFROMME + " INTEGER, "
			+ InviteMessgeDao.COLUMN_NAME_TIME + " TEXT); ";
			
			
	
	private DbOpenHelper(Context context) {
		super(context, getUserDatabaseName(), null, DATABASE_VERSION);
	}
	
	public static DbOpenHelper getInstance(Context context) {
		if (instance == null) {
			instance = new DbOpenHelper(context.getApplicationContext());
		}
		return instance;
	}
	
	private static String getUserDatabaseName() {
        return  HXSDKHelper.getInstance().getHXId() + "_demo.db";
    }
	
	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL(USERNAME_TABLE_CREATE);
		db.execSQL(INIVTE_MESSAGE_TABLE_CREATE);
		
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		
	}
	
	public void closeDB() {
	    if (instance != null) {
	        try {
	            SQLiteDatabase db = instance.getWritableDatabase();
	            db.close();
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	        instance = null;
	    }
	}
	
}

2. Dao 類規範


該類作用 : 將對數據庫增刪查改的操作都放在該類中;



(1) 維護 SQLiteOpenHelper 變量


維護變量 : 在 Dao 類中, 維護該變量, 方法中使用 OpenHelper 快速獲取數據庫;



(2) 在方法中實時獲取 SQLiteDatabase 變量


獲取數據庫對象 : 如果對數據庫進行操作時, 需要在方法中根據需求獲取 dbHelper.getWritableDatabase() 或者 dbHelper.getReadableDatabase() 數據庫對象;


(3) Dao 代碼示例


/**
 * Copyright (C) 2013-2014 EaseMob Technologies. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.easemob.chatuidemo.db;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.text.TextUtils;

import com.easemob.chatuidemo.Constant;
import com.easemob.chatuidemo.domain.User;
import com.easemob.util.HanziToPinyin;

public class UserDao {
	public static final String TABLE_NAME = "uers";
	public static final String COLUMN_NAME_ID = "username";
	public static final String COLUMN_NAME_NICK = "nick";
	public static final String COLUMN_NAME_IS_STRANGER = "is_stranger";

	private DbOpenHelper dbHelper;

	public UserDao(Context context) {
		dbHelper = DbOpenHelper.getInstance(context);
	}

	/**
	 * 保存好友list
	 * 
	 * @param contactList
	 */
	public void saveContactList(List<User> contactList) {
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		if (db.isOpen()) {
			db.delete(TABLE_NAME, null, null);
			for (User user : contactList) {
				ContentValues values = new ContentValues();
				values.put(COLUMN_NAME_ID, user.getUsername());
				if(user.getNick() != null)
					values.put(COLUMN_NAME_NICK, user.getNick());
				db.replace(TABLE_NAME, null, values);
			}
		}
	}

	/**
	 * 獲取好友list
	 * 
	 * @return
	 */
	public Map<String, User> getContactList() {
		SQLiteDatabase db = dbHelper.getReadableDatabase();
		Map<String, User> users = new HashMap<String, User>();
		if (db.isOpen()) {
			Cursor cursor = db.rawQuery("select * from " + TABLE_NAME /* + " desc" */, null);
			while (cursor.moveToNext()) {
				String username = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_ID));
				String nick = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_NICK));
				User user = new User();
				user.setUsername(username);
				user.setNick(nick);
				String headerName = null;
				if (!TextUtils.isEmpty(user.getNick())) {
					headerName = user.getNick();
				} else {
					headerName = user.getUsername();
				}
				
				if (username.equals(Constant.NEW_FRIENDS_USERNAME) || username.equals(Constant.GROUP_USERNAME)) {
					user.setHeader("");
				} else if (Character.isDigit(headerName.charAt(0))) {
					user.setHeader("#");
				} else {
					user.setHeader(HanziToPinyin.getInstance().get(headerName.substring(0, 1))
							.get(0).target.substring(0, 1).toUpperCase());
					char header = user.getHeader().toLowerCase().charAt(0);
					if (header < 'a' || header > 'z') {
						user.setHeader("#");
					}
				}
				users.put(username, user);
			}
			cursor.close();
		}
		return users;
	}
	
	/**
	 * 刪除一個聯系人
	 * @param username
	 */
	public void deleteContact(String username){
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		if(db.isOpen()){
			db.delete(TABLE_NAME, COLUMN_NAME_ID + " = ?", new String[]{username});
		}
	}
	
	/**
	 * 保存一個聯系人
	 * @param user
	 */
	public void saveContact(User user){
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		ContentValues values = new ContentValues();
		values.put(COLUMN_NAME_ID, user.getUsername());
		if(user.getNick() != null)
			values.put(COLUMN_NAME_NICK, user.getNick());
		if(db.isOpen()){
			db.replace(TABLE_NAME, null, values);
		}
	}
}



.


Tags: Android listener activity business domain

文章來源:


ads
ads

相關文章
ads

相關文章

ad