.


简介 : Android 常用的代码结构, 包括包的规范, 测试用例规范, 数据库模块常用编写规范;


参考: 之前写的一篇博客【Android 应用开发】 Application 使用分析;

--Application 分析: Application 概念, 声明周期, 组件间传递数据作用, 数据缓存作用;

--源码分析: 分析 Application 结构接口源码;

--使用示例: 自定义 Application 注册, 保存崩溃日志到文件, 监听Activity声明周期;





一. 包结构规范



1. 基本包, 业务包, 测试包


包基础结构 :

-- base 包 : 应用中常用的公共包 和 类放在该包中, 例如 工具类, SQLiteOpenHelper, 配置类, Application, 各种类的基类 等;

-- business 包 : 应用中的实际业务包, 这个包存放 与 app 业务相关的具体实现的类 和 包;

-- test 包 : 用于存放单元测试 和 测试用例相关的包;


示例 :

【Android 应用开发】 Android 相关代码规范 更新中 ...



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;}@Overridepublic 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";    }@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(USERNAME_TABLE_CREATE);db.execSQL(INIVTE_MESSAGE_TABLE_CREATE);}@Overridepublic 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);}}}




.

更多相关文章

  1. Android联系人数据库全解析(1)
  2. [转」android中的数据库操作
  3. 数据存储和界面展示一
  4. android中的数据库操作ZZ
  5. 系出名门Android(9) - 数据库支持(SQLite),
  6. android 全局变量 Application
  7. android数据库
  8. android 中的全局变量问题
  9. [Android 数据库] Android数据库总结

随机推荐

  1. android dialog 动画
  2. Android 如何开发 Bottom Navigation 风
  3. Android无法解锁debug
  4. Android——Activity四种启动模式
  5. Android View的介绍和使用
  6. android加密解密完美教程
  7. android api 中文 (74)—— AdapterView.Ad
  8. Android 之 下拉框(Spinner)的简单使用
  9. MTK Android Driver:led
  10. Android,LIstView中的OnItemClick点击无