安卓聊天软件

设计模式

public class OnMap {
	private HashMap<Integer, ClientActivity>clientMap;
	private static OnMap instance;//此静态实例类加载完成后就一直存在
	public static OnMap getInstance() {
		if (instance==null) 
			instance=new OnMap();
		return instance;
	}
	private OnMap() {
		clientMap=new HashMap<Integer, ClientActivity>();
	}
}

采用单例模型,此时线程是不安全的,(访问量较小时可忽略)因为当instance为null时,如果A和B同时访问,就会产生两个实例。可以给其加上锁,使其线程安全。

public class OnMap {
	private HashMap<Integer, ClientActivity>clientMap;
	private static OnMap instance;//此静态实例类加载完成后就一直存在
	public static OnMap getInstance() {
		if (instance==null) 
			synchronized (OnMap.class) {
				if (instance == null) {
					instance=new OnMap();
				}
			}

		return instance;
	}
	private OnMap() {
		clientMap=new HashMap<Integer, ClientActivity>();
	}
}

1.数据库设计:

在这里插入图片描述
id使用AUTO_INCREMENT保证唯一编号。

2.功能介绍:

2.1登录

输入账号和密码之后即登录,新用户则点击右下方按钮进行注册。

2.2注册

初次进入该界面会申请照片的权限,可以通过现在拍摄和图库中选择照片两种方式设置头像。用户的账号是自动生成的。

2.2.1如何自动生成不重复账号

public static String randomNumber(int num) {
        Random random = new Random();
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < num; i++) {
            str.append(random.nextInt(9));
        }
        return str.toString();
    }

生成一个num位的随机字符串。当同时申请的人数较少时,此时生成的字符串基本都是不一样的。

2.2.2如何判断客户端是进行登录还是注册

public enum TranObjectType {
    REGISTER, // 注册
    LOGIN, // 用户登录
    MESSAGE, // 用户发送消息
    SEARCH_FRIEND,//找朋友
    FRIEND_REQUEST;//好友申请
}

使用一个枚举类,列出所有的可能,在Listen监听线程中用case判断消息类型。

2.2.3如何确保数据库的插入语句是否执行完毕

try {
			//传入一个false,这样将不会自动提交,而需要使用con.commit()方法,手动提交事务,
			con.setAutoCommit(false);
		} catch (SQLException e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		PreparedStatement ps;
		try {
			ps=con.prepareStatement(sql0);
			ps.execute();
			
			ps=con.prepareStatement(sql1);
			ps.setString(1, user.getAccount());
			ps.setString(2, user.getUserName());
			ps.setBytes(3, user.getPhoto());
			//System.out.println("照片长度为"+user.getPhoto().length);
			ps.setDate(4, new java.sql.Date(user.getBirthday().getTime()));
			ps.setString(5, user.getPassword());
			ps.setInt(6, user.getGender());
			System.out.println("语句为"+sql1);
			ps.executeUpdate();
			con.commit();
		} catch (SQLException e) {
			// TODO: handle exception
			try {
				System.out.println("插入数据库异常,正在进行回滚....");
				con.rollback();
			} catch (Exception e2) {
				// TODO: handle exception
				e2.printStackTrace();
			}
			e.printStackTrace();
		}

使用事务,确保语句能正确执行,否则回滚。

2.3添加好友

通过好友的账号来搜索,输入对方的账号后,就点击查找,就进入了该界面。

此时,对方点击该条消息后,会弹出一个对话框。

2.3.1 如何将好友结果发送到客户端

public class TranObject implements Serializable {
    private static final long serialVersionUID=1L;
    private Object object;
    private  TranObjectType tranType;
    private Result result;
    private String sendTime;
    private int sendId;
    private int receiveId;
    private  String sendName;
}

将目标序列化之后发送,在客户端进行反序列化。

2.4收发消息

2.4.1如何处理多人向同一个好友发信息

private LinkedList<TranObject> sendQueue;
public synchronized void insertQueue(TranObject tran) {
		sendQueue.add(tran);
	}

使用一个队列sendQueue来维护所有人向该用户发送的消息,用synchronized修饰,保证每次只能有一个用户将消息加入到消息队列之中。
服务器会实时检测sendQueue的大小,当sendQueue的大小不为0的时候,向客户端转发消息。

2.4.1实时转发与离线转发

public void sendFriend(TranObject tran) {
		ClientActivity friendClient = null;
		if (mServer.contatinId(tran.getReceiveId())) {
			friendClient = mServer.getClientByID(tran.getReceiveId());
			friendClient.insertQueue(tran);
		} else {
			SaveMsgDao.insertSaveMsg(user.getId(), tran);
		}
	}

当好友在线的时候,转发的消息不存入数据库,而是直接转发给对方,增加实时性,客户端通过handler来更新UI。当好友不在线的时候。存入数据库,当好友上线的时候,会自动读取离线消息,读取之后用SQLite存储在本机。读取之后,服务器端的数据库会删除他的所有离线信息。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值