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

Android中Thread.start()无法解析符号问题及类调用咨询

问题解答

1. 出现"cannot resolve symbol 'start'"错误的原因

  • 类定义语法错误:你写的public class ExecThread(String id)完全不符合Java语法,正确的类定义应该是public class ExecThread,构造方法才是public ExecThread(String id),你把类声明和构造方法混在了一起。
  • 代码执行位置错误:thread.start();直接写在类的成员变量声明区域,Java不允许在类的顶级作用域直接执行方法调用这类语句,只能在构造方法、普通方法或代码块里执行。
  • 额外问题:代码里还有未定义的变量(a_string、ipAddress、port),而且子线程直接调用te.setText()操作UI,这在Android里会触发CalledFromWrongThreadException,后续也需要修正。

2. 在Fragment按钮点击事件中调用ExecThread的正确方式

先修正ExecThread类的写法,使其符合Java和Android规范,再在Fragment的按钮点击逻辑中实例化该类。

修正后的ExecThread类

package com.sample.ui.dashboard;

import android.os.Handler;
import android.os.Looper;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

public class ExecThread {
    private final String requestA;
    private final TextView textView;
    private final String ipAddress;
    private final int port;
    // 用于子线程切换到主线程更新UI的Handler
    private final Handler mainHandler = new Handler(Looper.getMainLooper());

    // 正确的构造方法
    public ExecThread(String id, String requestA, TextView textView, String ipAddress, int port) {
        this.requestA = requestA;
        this.textView = textView;
        this.ipAddress = ipAddress;
        this.port = port;
        // 在构造方法内启动轮询线程
        startPolling();
    }

    private void startPolling() {
        Runnable runnable = new Runnable() {
            String read = null;
            int count = 5;

            @Override
            public void run() {
                try {
                    while (count != 0) {
                        Socket socket = new Socket(ipAddress, port);
                        socket.setKeepAlive(true);
                        OutputStream out = socket.getOutputStream();
                        PrintWriter output = new PrintWriter(out, true);
                        output.println(requestA);
                        BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                        read = input.readLine();

                        if (read != null && read.length() >= 250) {
                            final String updateText = String.valueOf(count) + " - " + read.substring(4, 16);
                            // 通过Handler切换到主线程更新UI
                            mainHandler.post(() -> textView.setText(updateText));
                        }
                        socket.close();
                        count--;
                        // 24小时轮询需添加间隔延迟,示例为1秒,可根据实际调整
                        Thread.sleep(1000);
                    }
                } catch (IOException | InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
    }
}

在Fragment中调用ExecThread

在你的Fragment的按钮点击事件里,获取必要参数后实例化ExecThread:

public class DashboardFragment extends Fragment {
    private TextView meterNumberTv;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_dashboard, container, false);
        meterNumberTv = view.findViewById(R.id.meternumber);
        Button pollBtn = view.findViewById(R.id.poll_button); // 替换为你实际的按钮ID

        pollBtn.setOnClickListener(v -> {
            // 替换为实际业务参数
            String deviceId = "device_001";
            String requestA = "your_modbus_request_content";
            String ipAddress = "192.168.1.100";
            int port = 502; // Modbus默认端口,按需修改

            // 实例化线程类,启动硬件轮询
            new ExecThread(deviceId, requestA, meterNumberTv, ipAddress, port);
        });

        return view;
    }
}

额外注意事项

  • 24小时长期轮询建议用ScheduledExecutorService实现定时任务,比Thread.sleep()更稳定,也方便后续停止轮询。
  • 网络操作需要在AndroidManifest.xml中添加权限:<uses-permission android:name="android.permission.INTERNET"/>。
  • Fragment销毁时要停止轮询线程,避免内存泄漏,可以给ExecThread添加停止方法,在Fragment的onDestroyView()中调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 00:01:10