編輯:關於Android編程
特簡單, 沒有數據庫, 還沒有處理各種異常。
登錄:輸入用戶名點擊的登錄即可。
發送消息: 特定格式->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:uid public 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; }
希望本文所述對大家學習有所幫助。
Android Monitor包含一個CPU Monitor,可以讓你非常方便的監測你的應用的CPU的使用。它顯示試試的CPU使用。在CPU Monitor顯示正在運行的
** 安全對一些涉及到直接的金錢交易或個人隱私相關的應用的重要性是不言而喻的。Android系統由於其開源的屬性,市場上針對開源代碼定制的ROM參差
還原堆內存溢出的錯誤首先來還原一下堆內存溢出的錯誤。首先在SD卡上放一張照片,分辨率為(3776 X 2520),大小為3.88MB,是我自己用相機拍的一張照片。應用的布
第一部本文也主要是一步步分析spydroid源碼。 首先spydroid的采用的協議是RTSP,目前我知道支持RTSP協議的服務器是Darwin,但是Darwin比較復雜