You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android WiFi通信可发送数据但无法接收Handler响应问题求助

Android WiFi TCP通信接收无响应问题(Handler未被调用)

我正在开发一款实现Android与WiFi设备通信的App,目前数据发送正常,但无法接收设备响应,核心原因是负责接收的Handler从未被调用。

Wifi终端页面代码(wifi_terminal类)

public class wifi_terminal extends AppCompatActivity {

    ListView logListView;
    private static ChatAdapter adapter;
    private ArrayList<ChatMessage> chatHistory;
    Button sendButton;
    EditText editText;

    TCPConversation wifiCommn;
    byte[] resbyts;
    String response;
    boolean aBoolean =false;
    boolean isInDiagstate =false;
    boolean stopLiveParams =false;

    private Context context;
    private final String TAG = "WIFI Terminal Activity";
    Timer timer;
    WifiSemaphoreService wifiSemaphoreService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_wifi_terminal);

        init();

    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        finish();
    }

    private void init(){

        context = wifi_terminal.this;
        wifiSemaphoreService = new WifiSemaphoreService();
        wifiCommn = Singletone.getTcpConversation();
        wifiCommn.AssignHandler(mhandler);
        TCPConversation.responseCase =1;

        logListView= findViewById(R.id.loglistView);
        logListView.setItemsCanFocus(true);
        logListView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);

        loadDummyHistory();

        sendButton = findViewById(R.id.sendTextid);
        editText= findViewById(R.id.editTextid);

        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(wifiCommn!=null && !wifiCommn.CheckConnection())
                {
                    String  message=editText.getText().toString();


                    if(!message.equals(""))
                    {
                        message=message+"\r\n";
                        final String finalMessage = message;
                        Thread thread = new Thread(new Runnable() {
                            @Override
                            public void run() {
                                wifiCommn.responseCase =1;

                                wifiCommn.Send(finalMessage.getBytes());
                                final String finalMessage1 = finalMessage.replace("\r\n","").toString();
                                PrintConv( finalMessage1,true);
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        editText.setText("");
                                    }
                                });
                            }
                        });
                        thread.start();

                    }
                    else
                    {
                        Toast.makeText(context, "Enter some command!", Toast.LENGTH_SHORT).show();
                    }
                }
                else
                {
                    PrintConv( "SOCKET CONN LOST",true);
                    Toast.makeText(wifi_terminal.this, "SOCKET CONN LOST", Toast.LENGTH_SHORT).show();
                }
            }
        });


    }


    Handler mhandler = new Handler(new Handler.Callback()
    {
        @Override
        public boolean handleMessage(Message message)
        {
            switch(message.what)
            {
                case 11:
                    resbyts = (byte[]) message.obj;
                    response= new String(resbyts);

                    if(response.length()>0){
                        response = response.replace("\r\n","").toString();
                        aBoolean =true;
                        PrintConv(response,false);
                    }
                    else{

                        PrintConv("No Response",false);
                    }



                    break;

                case 22:
                    String responseString=(String) message.obj;
                    if(wifiCommn!=null && wifiCommn.CheckConnection())
                    {
                        wifiCommn.TerminateConnection();
                        PrintConv("CONNECTION LOST",false);
                    }
                    Toast.makeText(context, responseString, Toast.LENGTH_SHORT).show();
                    finish();

                    break;
            }
            return true;
        }
    });

    public void displayMessage(ChatMessage message)
    {
        adapter.add(message);
        adapter.notifyDataSetChanged();
        scroll();
    }
    private void scroll() { logListView.setSelection(logListView.getCount() - 1); }
    private void loadDummyHistory()
    {
        chatHistory = new ArrayList<>();
        ChatMessage msg = new ChatMessage();
        msg.setId(1);
        msg.setMe(false);
        msg.setDate(DateFormat.getDateTimeInstance().format(new Date()));
        chatHistory.add(msg);

        adapter = new ChatAdapter(wifi_terminal.this, new ArrayList<ChatMessage>());
        logListView.setAdapter(adapter);


    }

    public void PrintConv(final String msg, final boolean val)
    {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                ChatMessage chatMessage = new ChatMessage();
                chatMessage.setId(11);//dummy
                chatMessage.setMessage(msg);
                chatMessage.setDate(DateFormat.getDateTimeInstance().format(new Date()));
                chatMessage.setMe(val);
                displayMessage(chatMessage);
            }
        });
    }

}

WiFi通信核心类(WifiComm类)

public class WifiComm {

private Socket socket;
Handler handler;
private boolean minusOne =false;
public static int responseCase;
private int counter;
private Timer timer;
ArrayList<Integer> arr_byte = new ArrayList<Integer>();


static  ArrayList<Byte> readMessage2 = new ArrayList<>();

public WifiComm(Socket socket1)
{
    socket = socket1;

    Receiving recievingThread = new Receiving(socket);
    recievingThread.start();
}


public  void AssignHandler(Handler mhandler)
{
    handler = mhandler;
}
static  byte[] tempBuffer = new byte[2048];

public class Receiving extends Thread
{
    private Receiving(Socket socket1) {
        socket =socket1;
    }

    @Override
    public void run()
    {


        boolean recieveData =false;
        ArrayList<Byte>  readMessage1 =  new ArrayList<>();
        StringBuilder readMessage2 = new StringBuilder();
        ArrayList<Byte> readMessage3 = new ArrayList<>();
        minusOne =false;
        tempBuffer = new byte[2048];
        while (true)
        {

            try {
                int size=0;
                size   = socket.getInputStream().read(tempBuffer);
                //  Log.e("E",new String(tempBuffer));
              //  Log.e("Socket res:",new String(tempBuffer));

                switch (responseCase)
                {
                    case 1:/*Checks response until  "\n" comes*/
                        //readMessage1 = new StringBuilder();
                        String read = new String(tempBuffer,0,size);
                        for (int i = 0; i < size; i++) {
                            if (tempBuffer[i] == ':') {
                                recieveData = true;
                                readMessage1.add(tempBuffer[i]);
                            } else if (tempBuffer[i] == '\n') {
                                readMessage1.add(tempBuffer[i]);
                                byte[] tempByte = new byte[readMessage1.size()];
                                for (int j = 0; j < readMessage1.size(); j++) {
                                    tempByte[j] = readMessage1.get(j);
                                }
                                Log.e("BC1",readMessage1.toString());
                                readMessage1 = new ArrayList<>();

                                handler.obtainMessage(11,  tempByte).sendToTarget();
                                // CollectLogData(" RX :"+new String(tempByte));
                                recieveData = false;
                                tempBuffer = new byte[2048];
                            } else {
                                if (recieveData) {
                                    readMessage1.add(tempBuffer[i]);
                                }
                            }


                        }

                        break;
                    case 2:/*Checks response until  "#" comes*/
                        String read2 = new String(tempBuffer);
                        Log.e("BC2",read2);
                        for(int i=0; i<tempBuffer.length; i++)
                        {
                            switch (read2.charAt(i))
                            {
                                case '\n':
                                    readMessage2.append(read2.charAt(i));
                                    tempBuffer = new byte[2048];
                                    byte[] temp2 =readMessage2.toString().getBytes();

                                    handler.obtainMessage(11, temp2).sendToTarget();
                                    //Log.e("BC n :",readMessage2.toString());

                                    readMessage2 = new StringBuilder();
                                    break;



                                default:
                                    readMessage2.append(read2.charAt(i));
                                    break;
                            }
                        }
                        break;

                    case 3:
                        try
                        {
                            Log.e("BC Res :",new String(tempBuffer));
                            for(int i=0 ; i<size ; i++)
                            {
                                if(size>=2 && tempBuffer[i] == 4 && tempBuffer[i-1]!=5)
                                {
                                    readMessage3.add(tempBuffer[i]);
                                    byte[] tempByte = new byte[readMessage3.size()];
                                    for(int j=0;j<readMessage3.size();j++)
                                    {
                                        tempByte[j] = readMessage3.get(j);
                                    }
                                    handler.obtainMessage(11, tempByte).sendToTarget();
                                    Log.e("BC ResBytes STN:",new String(tempBuffer));
                                    readMessage3.clear();
                                    readMessage3 = new ArrayList<>();
                                    tempBuffer = new byte[8094];
                                }
                                else {
                                    readMessage3.add(tempBuffer[i]);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            // CollectLogData(" excp @ STN hanlder :"+e.getMessage());

                            e.printStackTrace();
                        }
                        break;
                }
            }
            catch (IOException e)
            {
                minusOne=true;
                handler.obtainMessage(22, "Socket Connection Lost!").sendToTarget();
                e.printStackTrace();
                break;
            }
        }

    }
}


public static void clearBuffer()
{
    readMessage2 = new ArrayList<>();
}
public void Send(final byte[] bite)
{
    final byte[] msg;
    msg=bite;
    Thread t =  new Thread(new Runnable() {
        @Override
        public void run() {
            try
            {
                socket.getOutputStream().write(msg);
                Log.e("BlueComm SENT ",new String(msg));
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    });
    t.start();
}

public void TerminateConnection()
{
    if(socket.isConnected())
    {
        try {
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
public boolean CheckConnection()
{
    /*Something made socket disconnected*/
    return minusOne;
}
}

问题排查与修复建议

1. Handler赋值时机错误

WifiComm构造函数中直接启动了接收线程,但此时Handler还未通过AssignHandler方法赋值,导致接收线程中handler为null,无法发送消息。

修复:将接收线程的启动逻辑从构造函数中分离,改为手动调用:

// WifiComm类修改
public WifiComm(Socket socket1) {
    socket = socket1;
}

public void startReceiving() {
    Receiving recievingThread = new Receiving(socket);
    recievingThread.start();
}

// wifi_terminal的init方法修改
wifiCommn = Singletone.getTcpConversation();
wifiCommn.AssignHandler(mhandler);
WifiComm.responseCase = 1; // 修正类名错误(原代码写的是TCPConversation)
wifiCommn.startReceiving(); // 先赋值Handler再启动线程

2. responseCase类名不匹配

原代码中设置的是TCPConversation.responseCase=1,但实际接收线程使用的是WifiComm.responseCase,导致switch分支未进入预期的case 1。

修复:统一改为WifiComm.responseCase=1。

3. 数据接收触发条件限制过严

case 1的逻辑要求必须先接收到:才开始收集数据,直到\n才发送消息。如果设备响应中没有:,则永远不会触发Handler消息。

修复:根据实际设备响应格式调整逻辑,比如直接收集所有字节直到换行:

case 1:/*Checks response until  "\n" comes*/
    String read = new String(tempBuffer,0,size);
    for (int i = 0; i < size; i++) {
        if (tempBuffer[i] == '\n') {
            readMessage1.add(tempBuffer[i]);
            byte[] tempByte = new byte[readMessage1.size()];
            for (int j = 0; j < readMessage1.size(); j++) {
                tempByte[j] = readMessage1.get(j);
            }
            Log.e("BC1", new String(tempByte));
            readMessage1.clear();
            if (handler != null) { // 增加空判断避免NPE
                handler.obtainMessage(11, tempByte).sendToTarget();
            }
            tempBuffer = new byte[2048];
        } else {
            readMessage1.add(tempBuffer[i]); // 直接收集所有字节
        }
    }
    break;

4. 增加调试日志

在接收线程读取到数据后,添加日志确认是否真的接收到设备响应:

size = socket.getInputStream().read(tempBuffer);
Log.e("Receiving", "Received " + size + " bytes: " + new String(tempBuffer, 0, size));

内容的提问来源于stack exchange,提问作者HarmanPreet Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 03:47:05