显示数据
写一个读的线程ReadThread
//从服务器读数据
public class ReadThread extends Thread{
SocketConnection socketConnection;
boolean isRunning = false;
public ReadThread(SocketConnection socketConnection) {
this.socketConnection = socketConnection;
this.start();
}
@Override
public void run() {
while (isRunning){
try {
String data = socketConnection.bufferedReader.readLine();
if(data!=null){
//读到数据,给控制器发消息
Controller.handleMessage(Controller.MSG_SHOW,data);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
SocketConnection中
//长连接
public class SocketConnection extends Thread {
......
BufferedReader bufferedReader;
ReadThread readThread;
......
@Override
public void run() {
try {
......
//读的对象
//因为通过socket只能拿到一个InputStream
//InputStream功能比较弱,只能读byte[]
InputStream inputStream = socket.getInputStream();
//InputStream被封装成InputStreamReader后可以读char[]字符
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
//BufferedReader不仅可以读char[]而且可以readLine()
bufferedReader = new BufferedReader(inputStreamReader);
readThread = new ReadThread(this);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Controller
//如果从主线程调handleMessage,handleMessage就运行在主线程
//如果从readThread调handleMessage,handleMessage就运行在工作线程
public static void handleMessage(int msgId,Object data){
//不同消息做不同处理
switch (msgId){
......
case MSG_SHOW:
//从model接收数据
final String friendContent = (String)data;
//调view显示
ChatActivity.instance.runOnUiThread(new Runnable() {
@Override
public void run() {
ChatActivity.instance.tv.append(friendContent+"\n");
}
});
case MSG_CLOSE:
break;
}
}
ChatActivity
public class ChatActivity extends AppCompatActivity {
......
public TextView tv;
public static ChatActivity instance;
@Override
protected void onCreate(Bundle savedInstanceState) {
......
tv = findViewById(R.id.tv);
instance = this;
......
}
......
}
优化
控制显示的代码不应该放在Controller中,应该放在Activity中,所以Controller中handleMessage中MSG_SHOW的相关代码应该移走,改为
case MSG_SHOW:
//从model接收数据
final String friendContent = (String)data;
//调view显示
ChatActivity.instance.runOnUiThread(new Runnable() {
@Override
public void run() {
ChatActivity.instance.handleShow(friendContent);
}
});
break;
ChatActivity中增加handleShow()方法
public void handleShow(String data){
ChatActivity.instance.tv.append(data+"\n");
}
关闭
SocketConnection增加关闭方法
public void close() {
try {//给服务器发消息,告诉服务器客户端退出
send("exit");
sleep(10);
//关线程
writeThread.isRunning = false;
readThread.isRunning = false;
//关连接
socket.shutdownOutput();
socket.shutdownInput();
printWriter.close();
bufferedReader.close();
socket.close();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Controller中如果收到有人发close消息
case MSG_CLOSE:
SocketConnection.newInstance().close();
break;
ChatActivity中增加一个关闭按钮,点击执行关闭操作
public class ChatActivity extends AppCompatActivity {
......
public TextView btn_close;
public static ChatActivity instance;
@Override
protected void onCreate(Bundle savedInstanceState) {
......
btn_close = findViewById(R.id.btn_close);
btn_close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Controller.handleMessage(Controller.MSG_CLOSE,null);
}
});
}
......
}