Android实践(websocket通信实现)-客户端实现

本文介绍了一个基于Android的石头剪刀布游戏应用,重点在于实现玩家间的实时对战功能。通过使用WebSocket技术,文章详细阐述了客户端和服务端的交互过程,包括库配置、UI设计、逻辑代码实现等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

新的开始,新的知识。

在学习安卓的过程中,有一个是关于做石头剪刀布游戏的左右,我设法想实现人对人对战,正好想尝试一下websocket编程,本篇先写的是websocket客户端。

服务端可参考:

https://blog.youkuaiyun.com/Abit_Go/article/details/105702517

实现现象:

首先添加库配置文件。

implementation 'com.squareup.okhttp3:okhttp:3.14.2'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.alibaba:fastjson:1.1.71.android'

其次设定开始页面,用来输入用户名

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:ignore="NamespaceTypo">

    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_marginTop="10dp"
        android:text="欢迎来到石头剪刀布游戏"
        android:textColor="#000000"
        android:textSize="30dp" />


    <EditText
        android:layout_below="@+id/tv1"
        android:id="@+id/roomId"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入联机名字"
        android:paddingLeft="10dp"
        android:paddingTop="20dp"
        android:paddingRight="10dp" />

    <LinearLayout
        android:layout_below="@+id/roomId"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/submit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="left"
            android:layout_marginTop="5dp"
            android:text="进入房间" />

        <Button
            android:id="@+id/single"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:layout_marginLeft="200dp"
            android:layout_marginTop="5dp"
            android:text="人机对战" />
    </LinearLayout>


</RelativeLayout >

然后分别是游玩界面。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:ignore="NamespaceTypo">

    <TextView
        android:paddingTop="20dp"
        android:layout_gravity="center"
        android:id="@+id/msg"
        android:textColor="#000000"
        android:textSize="50dp"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:text="石头剪刀布"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:paddingTop="20dp"
        android:textSize="40dp"
        android:layout_gravity="center"
        android:text="显示消息"
        android:id="@+id/showMsg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:paddingTop="20dp"
        android:layout_gravity="center"
        android:text="挑战结果:"
        android:textSize="20dp"
        android:id="@+id/result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <LinearLayout
        android:paddingTop="40dp"
        android:layout_gravity="center"
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <Button
            android:layout_gravity="center_vertical"
            android:id="@+id/left"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="上一个" />
        <ImageButton
            android:layout_gravity="center"
            android:src="@mipmap/shitou"
            android:id="@+id/iv1"
            android:layout_width="500px"
            android:layout_height="500px" />
        <Button
            android:layout_gravity="center_vertical"
            android:text="下一个"
            android:id="@+id/right"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

    <Button
        android:layout_gravity="center"
        android:enabled="true"
        android:text="提交"
        android:id="@+id/submitJSON"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />


</LinearLayout >

最后是逻辑代码部分:

开始界面逻辑代码:

package com.example.game;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

public class ActivityStart extends AppCompatActivity {
    private EditText editText;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.start);
        initView();
    }
    void initView(){
        editText = findViewById(R.id.roomId);
        button = findViewById(R.id.submit);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(ActivityStart.this,ActivityPlay.class);
                String roomId = editText.getText().toString();
                intent.putExtra("roomId",roomId);
                if(roomId.equals("")){
                    Toast.makeText(ActivityStart.this,"房间号不能为空",Toast.LENGTH_SHORT).show();
                }
                startActivity(intent);
            }
        });
    }
}

游玩界面源码:

package com.example.game;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;

public class ActivityPlay extends AppCompatActivity {
    private TextView textView;
    private Button left;
    private Button right;
    private ImageButton imageView;
    private int index = 0;
    private Button submit;
    private WebSocket mSocket;
    private String name;
    //初始状态
    private int send=-1;
    private int value_0=-1;

    private TextView result;

    private int[] imgIndex = {R.mipmap.shitou, R.mipmap.jiandao, R.mipmap.bu};
    private String[] imgContant = {"石头","剪刀","布"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.playinterface);
        initView();
        start();
    }

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.arg1){
                case 1:
                    //连接成功
                    textView.setText(msg.obj.toString());
                    break;
                case 2:
                    //接收到的消息
                    String receive = msg.obj.toString();
                    JSONObject jsonObject = JSONObject.parseObject(receive);
                    value_0= jsonObject.getIntValue("value");
                    String name_O = jsonObject.getString("name");
                    //如果是自己发起的,那就直接接收即可
                    if (send==0){
                        send = -1;
                        submit.setEnabled(true);
                        if(value_0==index){
                            result.setText("结果:平局");
                        }else {
                            if((index+1)%3==value_0){
                                result.setText("结果:你赢了");
                            }else {
                                result.setText("结果:你输了");
                            }
                        }
                    }
                    //如果send等于-1的时候,证明是别人发过来的,
                    else if(send==-1){
                        textView.setText("请尽快猜拳");
                        submit.setEnabled(true);
                        //如果不是自己自己发起的,那就需要进行下一步的提交
                        send = 0;
                    }
                    break;
                case 3:
                    //关闭
                    textView.setText(msg.obj.toString());
                    break;
                case 4:
                    //失败
                    textView.setText(msg.obj.toString());
                    break;
            }
        }
    };


    private void start() {
        OkHttpClient mOkHttpClient = new OkHttpClient.Builder()
                .readTimeout(3, TimeUnit.SECONDS)//设置读取超时时间
                .writeTimeout(3, TimeUnit.SECONDS)//设置写的超时时间
                .connectTimeout(3, TimeUnit.SECONDS)//设置连接超时时间
                .build();

        Request request = new Request.Builder().url("ws://*.*.*.*:8989/websocket/"+name).build();
        EchoWebSocketListener socketListener = new EchoWebSocketListener();
        mOkHttpClient.newWebSocket(request, socketListener);
        mOkHttpClient.dispatcher().executorService().shutdown();
    }

    void initView() {
        textView = findViewById(R.id.showMsg);
        final Intent intent = getIntent();
        name = intent.getStringExtra("roomId");
        textView.setText(name);

        left = findViewById(R.id.left);
        left.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                index = ((index + 3) - 1) % 3;
                imageView.setImageResource(imgIndex[index]);
            }
        });
        right = findViewById(R.id.right);
        right.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                index = ((index + 3) + 1) % 3;
                imageView.setImageResource(imgIndex[index]);
            }
        });
        imageView = findViewById(R.id.iv1);
        submit = findViewById(R.id.submitJSON);
        submit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //自己先提交的数据
                //只要发送以下自己的名字以及index值即可
                if(send==-1){
                    send = 0;
                    JSONObject jsonObject= new JSONObject();
                    jsonObject.put("name",name);
                    jsonObject.put("value",index);
                    submit.setEnabled(false);
                    textView.setText("等待对方答映");
                    mSocket.send(jsonObject.toString());
                }
                //如果是0的时候那就是别人发过来的状态
                else if(send==0) {//true
                    //如果是别人先提交的数据
                    send = -1;
                    if(value_0==index){
                        result.setText("结果:平局");
                    }else {
                        if((index+1)%3==value_0){
                            result.setText("结果:你赢了");
                        }else {
                            result.setText("结果:你输了");
                        }
                    }
                    JSONObject jsonObject= new JSONObject();
                    jsonObject.put("name",name);
                    jsonObject.put("value",index);
                    submit.setEnabled(true);
                    mSocket.send(jsonObject.toString());
                }
            }
        });

        result = findViewById(R.id.result);
    }

    private final class EchoWebSocketListener extends WebSocketListener {

        @Override
        public void onOpen(WebSocket webSocket, Response response) {
            super.onOpen(webSocket, response);
            mSocket = webSocket;
//            String openid = "img1";
//            //连接成功后,发送登录信息
//            String message = "{\"type\":\"login\",\"user_id\":\"" + openid + "\"}";
//            mSocket.send(message);
            showInfo(1,"连接成功!");
        }

        @Override
        public void onMessage(WebSocket webSocket, ByteString bytes) {
            super.onMessage(webSocket, bytes);
            //接收消息
        }

        @Override
        public void onMessage(WebSocket webSocket, String text) {
            super.onMessage(webSocket, text);
            showInfo(2,text);

            //收到服务器端发送来的信息后,每隔25秒发送一次心跳包
            Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    mSocket.send("heartbeat");
                }
            }, 25000);
        }

        @Override
        public void onClosed(WebSocket webSocket, int code, String reason) {
            super.onClosed(webSocket, code, reason);
            //关闭
            showInfo(3,"closed:" + reason);
        }

        @Override
        public void onClosing(WebSocket webSocket, int code, String reason) {
            super.onClosing(webSocket, code, reason);
        }

        @Override
        public void onFailure(WebSocket webSocket, Throwable t, Response response) {
            super.onFailure(webSocket, t, response);
            showInfo(4,"failure:" + t.getMessage());
        }
    }
    void showInfo(int kind,String s){
        Message message = new Message();
        message.arg1=kind;
        message.obj = s;
        handler.sendMessage(message);
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值