Android之高仿QQ聊天

源码下载http://download.csdn.net/detail/weidi1989/4615696

转载请注明出处,谢谢!

源码中的一个bug,请修改,在LoginActivity,如下图所示:

国庆这几天,闲着无聊,仿照QQ2012,做了一个基于socket的聊天工具,由于代码比较多,我就不在文章中贴出代码,需要的朋友可以点击上面下载,谢谢,有什么问题或者bug,欢迎给我留言。

首先说一下我的整体思路:整个聊天是通过服务器转发的,这样处理起来比较简单,但是服务器压力会特别大。建议在真正做项目的时候,服务器只处理用户注册、登录以及判断用户是否掉线等,至于聊天、传文件以及视频等就在用户之间单独建立连接,这样可以大大减少服务器的压力,我这里就没考虑这么多了。

第一:我们定义一个超级消息对象(记得要序列化),它包含:消息类型、具体的消息对象、发送给谁以及来自谁。服务器和客户端就是通过发送这个超级消息对象来进行通讯的。

第二:服务器,在接受用户连接之后,马上把socket丢入线程池中,这样可以支持多用户并发访问,然后根据用户的socket对象,分别建立一条读消息线程写消息线程在这里,写消息线程要先建立,我们需要传递给读消息线程,因为我们在读完消息之后会给用户回复消息)。在读消息线程里面根据消息类型处理超级消息对象,分别是:注册、登录、下线、转发消息、文件、刷新好友列表等。后台数据库处理的话,我们通过dao模式,这样很方便,而且会使代码显得简洁、明了、有条理,总之是各种好,哈哈。最后要注意一点:因为我们是转发消息,所以在用户登录成功后,我们需要把该用户的写消息线程根据用户的ID存入一个Map中,以便在转发消息的时候,可以根据用户ID取出对应的写消息线程,从而实现转发消息。

第三:客户端,跟服务器类似,只是没有线程池,在用户连接上服务器之后,也是根据连接后的socket对象,分别建立一条读消息线程写消息线程然后在代码中哪里需要发消息,就通过get方法获取写消息线程,哪里需要读消息,就通过get方法获取读消息线程

第四:关于写消息线程处理,因为服务器或者客户端,不可能时时需要写消息,因此我们如果用一个死循环去处理写线程,明显的是不明智的,因此我做了一个简单的处理,在写消息的死循环中先wait(),当我们调用写消息线程的setMessage方法后,就notify唤醒写线程,发送完消息之后,继续wait(),这里我贴出核心代码:

	public void setMsg(TranObject msg) {
		this.msg = msg;
		synchronized (this) {
			notify();
		}
	}

	@Override
	public void run() {
		try {
			while (isStart) {
				if (msg != null) {
					oos.writeObject(msg);
					oos.flush();
					if (msg.getType() == TranObjectType.LOGOUT) {// 如果是发送下线的消息,就直接跳出循环
						break;
					}
					synchronized (this) {
						wait();// 发送完消息后,线程进入等待状态
					}
				}
			}
			oos.close();// 循环结束后,关闭输出流和socket
			if (socket != null)
				socket.close();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


第五:具体手机客户端的处理,因为android有自己的特点,也有自己的优势,所以我们要充分利用它的优势,避开他的缺点来处理消息,我说一下我在这个小项目中处理消息的思路:我在用户启动程序的时候,开启一个获取消息的service,在该service中建立连接,然后通过一个接口去监听读消息线程收到的消息,在收到消息的同时,把该超级消息对象通过广播发送出去然后自定义一个抽象的MyActivity继承Activity,在MyActivity里面通过一个广播接收者接收service中发送过来的消息,并通过一个抽象方法传递给子Activity,我们的其他activity如果要处理收消息,就可以继承我们自定义的MyActivity,然后实现那个抽象方法,就可以了这样很好的处理了不同的activity接收消息的缺点,而且后台处理也很方便,我不知道腾讯QQ在这个方面是怎么处理的,这是我个人的想法而已。下面贴出MyActivity的代码:

/**
 * 自定义一个抽象的MyActivity类,每个Activity都继承他,实现消息的接收(优化性能,减少代码重复)
 * 
 * @author way
 * 
 */
public abstract class MyActivity extends Activity {
	/**
	 * 广播接收者,接收GetMsgService发送过来的消息
	 */
	private BroadcastReceiver MsgReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			TranObject msg = (TranObject) intent
					.getSerializableExtra(Constants.MSGKEY);
			if (msg != null) {//如果不是空,说明是消息广播
				// System.out.println("MyActivity:" + msg);
				getMessage(msg);// 把收到的消息传递给子类
			} else {//如果是空消息,说明是关闭应用的广播
				close();
			}
		}
	};

	/**
	 * 抽象方法,用于子类处理消息,
	 * 
	 * @param msg
	 *            传递给子类的消息对象
	 */
	public abstract void getMessage(TranObject msg);

	/**
	 * 子类直接调用这个方法关闭应用
	 */
	public void close() {
		Intent i = new Intent();
		i.setAction(Constants.ACTION);
		sendBroadcast(i);
		finish();
	}

	@Override
	public void onStart() {// 在start方法中注册广播接收者
		super.onStart();
		IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction(Constants.ACTION);
		registerReceiver(MsgReceiver, intentFilter);// 注册接受消息广播

	}

	@Override
	protected void onStop() {// 在stop方法中注销广播接收者
		super.onStop();
		unregisterReceiver(MsgReceiver);// 注销接受消息广播
	}
}

好了,大概思路就是这样的,下面根据具体的测试截图,说说我的思路:

1.桌面快捷方式 2.欢迎界面

3.正在登陆 4.登陆成功后的好友列表,通过ActivityGroup实现

5.好友列表是自定义的ExpandableListView,可以下拉刷新6.群组功能未实现

7.聊天主界面, 8.程序后台运行的界面

9.好友上线提醒 10.未进入聊天界面,来消息提醒

11.后台运行来消息时提醒,有声音有振动

12.后台数据库,密码通过MD5方式加密了,用户注册成功后,即生成一个以用户id命名的表,用来保存好友。

13.服务器运行提示

14.注册成功后的提示窗

最后来几张聊天截图,好了今天就到这里,大家有什么好的建议,欢迎提,谢谢


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现 Android Studio 高仿 QQ 消息列表需要以下步骤: 1. 创建一个 RecyclerView 用于显示消息列表。 2. 创建一个 RecyclerView.Adapter,通过这个 Adapter 来绑定数据和消息列表的视图。 3. 在 Adapter 中实现 onCreateViewHolder、onBindViewHolder 和 getItemCount 方法。 4. 在 onCreateViewHolder 方法中,创建 ViewHolder,并加载消息列表项的布局文件。 5. 在 onBindViewHolder 方法中,绑定每个 ViewHolder 的数据和视图。 6. 在 getItemCount 方法中,返回消息列表项的数量。 7. 创建一个消息类,用于存储每个消息的相关信息,比如发送者、接收者、时间、内容等等。 8. 在 Activity 中创建一个 ArrayList 对象来存储消息。 9. 将 ArrayList 对象传递给 Adapter,并设置 Adapter 到 RecyclerView 上。 10. 运行程序,查看效果。 下面是一个简单的代码示例: 1. 创建一个 RecyclerView ```xml <android.support.v7.widget.RecyclerView android:id="@+id/rv_message_list" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 2. 创建一个 Adapter ```java public class MessageListAdapter extends RecyclerView.Adapter<MessageListAdapter.ViewHolder> { private ArrayList<Message> mMessageList; public MessageListAdapter(ArrayList<Message> messageList) { mMessageList = messageList; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_message, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(ViewHolder holder, int position) { Message message = mMessageList.get(position); holder.mTvSender.setText(message.getSender()); holder.mTvTime.setText(message.getTime()); holder.mTvContent.setText(message.getContent()); } @Override public int getItemCount() { return mMessageList.size(); } public static class ViewHolder extends RecyclerView.ViewHolder { public TextView mTvSender; public TextView mTvTime; public TextView mTvContent; public ViewHolder(View itemView) { super(itemView); mTvSender = (TextView) itemView.findViewById(R.id.tv_sender); mTvTime = (TextView) itemView.findViewById(R.id.tv_time); mTvContent = (TextView) itemView.findViewById(R.id.tv_content); } } } ``` 3. 创建一个消息类 ```java public class Message { private String mSender; private String mTime; private String mContent; public Message(String sender, String time, String content) { mSender = sender; mTime = time; mContent = content; } public String getSender() { return mSender; } public String getTime() { return mTime; } public String getContent() { return mContent; } } ``` 4. 在 Activity 中使用 Adapter 和 RecyclerView ```java public class MainActivity extends AppCompatActivity { private ArrayList<Message> mMessageList; private RecyclerView mRecyclerView; private MessageListAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mMessageList = new ArrayList<>(); mMessageList.add(new Message("Tom", "10:00", "Hello")); mMessageList.add(new Message("Jerry", "10:01", "Hi")); mMessageList.add(new Message("Tom", "10:02", "How are you?")); mMessageList.add(new Message("Jerry", "10:03", "I'm fine, thank you.")); mRecyclerView = (RecyclerView) findViewById(R.id.rv_message_list); mAdapter = new MessageListAdapter(mMessageList); mRecyclerView.setAdapter(mAdapter); mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); } } ``` 此时,我们就实现了一个简单的 Android Studio 高仿 QQ 消息列表。你可以根据自己的需求,修改布局文件和数据结构来满足各种需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值