zoukankan      html  css  js  c++  java
  • 【Android 应用开发】 Android 相关代码规范 更新中 ...

    .


    简介 : 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);
    		}
    	}
    }
    




    .

  • 相关阅读:
    python3.0与python2.0有哪些不同
    python常用内置模块,执行系统命令的模块
    06python 之基本数据类型
    python语言简介、解释器、字符编码介绍
    http协议&接口规范&接口测试入门
    基于APPIUM测试微信公众号的UI自动化测试框架(结合Allure2测试报告框架)
    SQL注入工具sqlmap的注入过程记录
    unittest框架
    测试转型之路--学习ing
    Tomcat分析-启动过程
  • 原文地址:https://www.cnblogs.com/hanshuliang/p/4215380.html
Copyright © 2011-2022 走看看