Android聊天工具基於socket實現_Android

來源:互聯網
上載者:User

特簡單, 沒有資料庫, 還沒有處理各種異常。
登入:輸入使用者名稱點擊的登入即可。
發送訊息: 特定格式->toUser:message
1. 伺服器:儲存線上使用者    

public class Online { private static Online mOnline = null; private LinkedHashMap<String, Socket> mOnlines = new LinkedHashMap<String, Socket>();   private Online() { }   public synchronized static Online getInstance() {  if(null == mOnline) {   mOnline = new Online();  }     return mOnline; }   public void put(String key, Socket socket) {  if(!mOnlines.containsKey(key)) {   mOnlines.put(key, socket);  } }   public Socket get(String key) {  return mOnlines.get(key); }   public void remove(String key) {  mOnlines.remove(key); }}

2. 伺服器:一個簡單的socket伺服器    

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket; // login:uid// send:fromuser:touser:message// logout:uidpublic class Server implements Runnable { private Socket mSocket; private Online mOnline;  public Server(Socket socket) {  mSocket = socket;  mOnline = Online.getInstance(); }  @Override public void run() {  try {   BufferedReader reader = new BufferedReader(new InputStreamReader(     mSocket.getInputStream()));   String cmd = reader.readLine();       // login   if (cmd.startsWith("login")) {    String userName = cmd.split(":")[1];    mOnline.put(userName, mSocket);    System.out.println(userName + " login...");         PrintWriter writer = new PrintWriter(mSocket.getOutputStream());    writer.println("success");    writer.flush();   } else if (cmd.startsWith("send")) {    System.out.println(cmd);    String[] cmds = cmd.split(":");    String from = cmds[1];    Socket to = mOnline.get(cmds[2]);    String msg = cmds[3];     PrintWriter writer = new PrintWriter(to.getOutputStream());    System.out.println("rec:" + from + ":" + cmds[2] + ":" + msg);         writer.println("rec:" + from + ":" + cmds[2] + ":" + msg);    writer.flush();   }else if (cmd.startsWith("logout")) {    System.out.println(cmd);         String user = cmd.split(":")[1];    mOnline.get(user).close();    mOnline.remove(user);         PrintWriter writer = new PrintWriter(mSocket.getOutputStream());    writer.println("success");    writer.flush();   }  } catch (Exception e) {   e.printStackTrace();  } }  public static void main(String[] args) throws Exception {  ServerSocket server = new ServerSocket(8888);  boolean flag = true;  while (flag) {   new Thread(new Server(server.accept())).start();   System.out.println("user in...");  }   server.close(); }}

3. 用戶端登入介面    

public class MainActivity extends Activity { private EditText mUser;   @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);     mUser = (EditText) findViewById(R.id.username); }   public void login(View view) {  final String userName = mUser.getText().toString().trim();  Login login = new Login(userName);  login.setOnLoginListener(new Login.LoginCallback() {   @Override   public void onLogin(boolean success) {    if(success) {     Intent intent = new Intent(MainActivity.this, Chat.class);     intent.putExtra("user", userName);     startActivity(intent);     finish();    }else {     Toast.makeText(MainActivity.this, "登入失敗", Toast.LENGTH_SHORT).show();    }   }  });     login.login(); }}

4. 處理登入    

public class Login { private String mUserName; private LoginCallback mCallback;   public Login(String userName) {  mUserName = userName; }   public void setOnLoginListener(LoginCallback callback) {  mCallback = callback; }   private Handler mHandler = new Handler() {  public void handleMessage(Message msg) {   switch (msg.what) {   case Constant.SUCCESS:    mCallback.onLogin(true);    break;   case Constant.FAILED:    mCallback.onLogin(false);    break;   }  }; };   public void login() {  new Thread(new Runnable() {   @Override   public void run() {    Socket socket = null;    try {     socket = new Socket();     socket.connect(new InetSocketAddress("192.168.100.100", 8888), 4000);     PrintWriter writer = new PrintWriter(socket.getOutputStream());     writer.println("login:" + mUserName);     writer.flush();           BufferedReader reader = new BufferedReader(       new InputStreamReader(socket.getInputStream()));     String line = reader.readLine();     System.out.println(line);     if("success".equals(line)) {      PConnection.socket = socket;      mHandler.sendEmptyMessage(Constant.SUCCESS);     }else {      mHandler.sendEmptyMessage(Constant.FAILED);     }    }catch(Exception e) {     e.printStackTrace();    }   }  }).start(); }   public interface LoginCallback {  public void onLogin(boolean success); }}

5. 聊天介面    

public class Chat extends Activity { private String mUserName; private EditText mEdit; private ListView mMessage;   private ReceiverMessage mRecMessage; private SendMessage mSendMesage; private List<Map<String, String>> mData = new ArrayList<Map<String, String>>(); private MessagesAdapter mAdapter;   @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.chat_layout);     mUserName = getIntent().getStringExtra("user");  mEdit = (EditText) findViewById(R.id.edit);  mMessage = (ListView) findViewById(R.id.message);     mRecMessage = new ReceiverMessage();  mRecMessage.setOnReceiverListener(new RecListener());  mRecMessage.run();     mSendMesage = new SendMessage();  mSendMesage.setOnSendListener(new SendListener());     mAdapter = new MessagesAdapter(this, mData);  mMessage.setAdapter(mAdapter); }   public void send(View view) {  String[] content = mEdit.getText().toString().trim().split(":");  mSendMesage.send(mUserName, content[0], content[1]); }   private class RecListener implements ReceiverMessage.OnReceiverListener {  @Override  public void onReceiver(String user, String msg) {   Map<String, String> temp = new HashMap<String, String>();   temp.put("user", user);   temp.put("msg", msg);   temp.put("pos", "right");   mData.add(temp);   mAdapter.notifyDataSetChanged();  } }   private class SendListener implements SendMessage.OnSendListener {  @Override  public void onSend(String[] msg) {   Map<String, String> temp = new HashMap<String, String>();   temp.put("user", "我");   temp.put("msg", msg[1]);   temp.put("pos", "left");   mData.add(temp);   mAdapter.notifyDataSetChanged();  } }   @Override public boolean onOptionsItemSelected(MenuItem item) {  if(R.id.logout == item.getItemId()) {   Logout logout = new Logout();   logout.setOnLogoutListener(new Logout.OnLogoutListener() {    @Override    public void onLogout(boolean success) {     if(success) {      Toast.makeText(Chat.this, "登出成功", Toast.LENGTH_SHORT).show();      finish();     }else {      Toast.makeText(Chat.this, "登出失敗", Toast.LENGTH_SHORT).show();     }    }   });       logout.logout(mUserName);  }     return super.onOptionsItemSelected(item); }   @Override public boolean onCreateOptionsMenu(Menu menu) {  getMenuInflater().inflate(R.menu.main, menu);  return super.onCreateOptionsMenu(menu); }}

6. 發送訊息    

public class SendMessage { private OnSendListener mListener;   public void setOnSendListener(OnSendListener listener) {  mListener = listener; }   private Handler mHandler = new Handler() {  public void handleMessage(Message msg) {   mListener.onSend((String[]) msg.obj);  }; };   // send:from:to:message public void send(final String from , final String to, final String msg) {  new Thread(new Runnable() {   @Override   public void run() {    Socket socket = null;    try {     socket = new Socket();     socket.connect(new InetSocketAddress("192.168.100.100", 8888), 4000);     PrintWriter writer = new PrintWriter(socket.getOutputStream());     writer.println("send:" + from + ":" + to + ":" + msg);     writer.flush();           Message message = mHandler.obtainMessage(       Constant.SUCCESS, new String[] {to, msg});           message.sendToTarget();    } catch(Exception e) {    } finally {     try {      socket.close();     } catch (IOException e) {      e.printStackTrace();     }    }   }  }).start(); }   public interface OnSendListener {  public void onSend(String[] msg); }}

7. 接收訊息,死迴圈,但阻塞,沒啥問題    

public class ReceiverMessage { private OnReceiverListener mListener; public void setOnReceiverListener(OnReceiverListener listener) {  mListener = listener; }   private Handler mHandler = new Handler() {  public void handleMessage(Message msg) {   String[] cmds = (String[]) msg.obj;   mListener.onReceiver(cmds[0], cmds[1]);  }; };   public void run() {  new Thread(new Runnable() {   @Override   public void run() {    try {     Socket socket = PConnection.socket;     while(true) {      System.out.println("wait for message...");      BufferedReader reader = new BufferedReader(        new InputStreamReader(socket.getInputStream()));      String line = reader.readLine();             if(line.startsWith("rec")) {       //rec:fromuser:touser:message       String[] cmds = line.split(":");       System.out.println(cmds[0] + ":" + cmds[1] + ":" + cmds[2] + ":" + cmds[3]);       Message msg = mHandler.obtainMessage(Constant.SUCCESS, new String[] {cmds[1], cmds[3]});       msg.sendToTarget();      }     }    } catch (Exception e) {     e.printStackTrace();    }   }  }).start(); }   public interface OnReceiverListener {  public void onReceiver(String user, String msg); }}

8. 登出登入    

public class Logout { public OnLogoutListener mListener;   public void setOnLogoutListener(OnLogoutListener listner) {  mListener = listner; }   private Handler mHandler = new Handler() {  public void handleMessage(Message msg) {   if(Constant.SUCCESS == msg.what) {    mListener.onLogout(true);   }else {    mListener.onLogout(false);   }  }; };   public void logout(final String user) {  new Thread(new Runnable() {   @Override   public void run() {    try {     Socket socket = new Socket();     socket.connect(new InetSocketAddress("192.168.100.100", 8888), 4000);     PrintWriter writer = new PrintWriter(socket.getOutputStream());     writer.println("logout:" + user);     writer.flush();           BufferedReader reader = new BufferedReader(       new InputStreamReader(socket.getInputStream()));           if("success".equals(reader.readLine())) {      PConnection.socket = null;      mHandler.sendEmptyMessage(Constant.SUCCESS);     }else {      mHandler.sendEmptyMessage(Constant.FAILED);     }    } catch (Exception e) {     e.printStackTrace();    }   }  }).start(); }   public interface OnLogoutListener {  public void onLogout(boolean success); }}

9. 存放登入後的socket,在發送訊息和接收訊息時使用該socket    

public class PConnection { public static Socket socket;}

希望本文所述對大家學習有所協助。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.