【达内课程】MVC项目练习-聊天项目(下)

文章目录

显示数据

在这里插入图片描述
写一个读的线程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);
            }
        });
    }
	......
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值