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

Android SDK 26下线程循环递增值的跨类回调问题求助

嘿,我来帮你搞定这个问题!你的场景是在Android SDK 26环境下,Class B内部启动了一个带while循环的线程,循环里递增整数并休眠X毫秒,现在想把每次递增后的数值反馈给其他类(比如初始化B的Class A),但B又不能依赖A的存在对吧?Callable确实不太适合这种持续输出结果的场景——它主要是给单次任务提供返回值的,咱们换几个更贴合需求的方案:

方案1:使用回调接口(最经典的解耦实现)

这是处理这类“单向通知”场景的标准做法,通过定义一个接口把B和接收方解耦,B只需要知道要调用这个接口的方法,不用关心具体是谁实现它。

步骤示例:

  1. 先定义一个回调接口,用来传递数值:
public interface OnCountUpdateListener {
    void onCountUpdated(int currentCount);
}
  1. 在Class B里添加这个接口的引用,并在循环中调用它:
public class ClassB {
    private OnCountUpdateListener mListener;
    private Thread mCountThread;
    private int count = 0;
    private static final long SLEEP_TIME = 1000; // 替换成你的X毫秒

    // 提供方法让外部设置监听器
    public void setOnCountUpdateListener(OnCountUpdateListener listener) {
        mListener = listener;
    }

    public ClassB() {
        startCountThread();
    }

    private void startCountThread() {
        mCountThread = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                count++;
                // 如果监听器存在,就把当前数值传出去
                if (mListener != null) {
                    // 注意:如果需要更新UI,要切回主线程,Android里可以用runOnUiThread或者Handler
                    mListener.onCountUpdated(count);
                }
                try {
                    Thread.sleep(SLEEP_TIME);
                } catch (InterruptedException e) {
                    // 捕获中断异常,退出循环
                    Thread.currentThread().interrupt();
                    e.printStackTrace();
                }
            }
        });
        mCountThread.start();
    }

    // 记得提供销毁方法,避免内存泄漏
    public void stopThread() {
        if (mCountThread != null) {
            mCountThread.interrupt();
        }
    }
}
  1. 在Class A里实现这个接口,初始化B的时候设置监听器:
public class ClassA {
    private ClassB mClassB;

    public ClassA() {
        mClassB = new ClassB();
        mClassB.setOnCountUpdateListener(new OnCountUpdateListener() {
            @Override
            public void onCountUpdated(int currentCount) {
                // 这里拿到每次递增后的数值,做你需要的操作
                Log.d("ClassA", "当前计数:" + currentCount);
            }
        });
    }

    // 比如在Activity的onDestroy里停止线程
    public void onDestroy() {
        if (mClassB != null) {
            mClassB.stopThread();
        }
    }
}

方案2:使用Android LiveData(适合Android生命周期场景)

如果你是在Android组件(比如Activity/Fragment)里接收数值,LiveData是更好的选择——它能自动感知组件生命周期,避免内存泄漏,还能在组件活跃时才接收更新。

步骤示例:

  1. 在Class B里创建MutableLiveData:
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.LiveData;

public class ClassB {
    private MutableLiveData<Integer> mCountLiveData = new MutableLiveData<>();
    private Thread mCountThread;
    private int count = 0;
    private static final long SLEEP_TIME = 1000;

    public ClassB() {
        startCountThread();
    }

    // 对外暴露不可变的LiveData,避免外部直接修改
    public LiveData<Integer> getCountLiveData() {
        return mCountLiveData;
    }

    private void startCountThread() {
        mCountThread = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                count++;
                // postValue可以在子线程调用,自动切换到主线程分发
                mCountLiveData.postValue(count);
                try {
                    Thread.sleep(SLEEP_TIME);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    e.printStackTrace();
                }
            }
        });
        mCountThread.start();
    }

    public void stopThread() {
        if (mCountThread != null) {
            mCountThread.interrupt();
        }
    }
}
  1. 在Class A(比如Activity)里观察LiveData:
public class ClassA extends AppCompatActivity {
    private ClassB mClassB;

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

        mClassB = new ClassB();
        // 观察LiveData,只有在Activity活跃时才会收到回调
        mClassB.getCountLiveData().observe(this, currentCount -> {
            // 处理收到的数值
            Log.d("ClassA", "当前计数:" + currentCount);
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mClassB.stopThread();
    }
}

为什么Callable不适合你的场景?

Callable是为单次异步任务设计的——它执行完一次任务后返回一个结果,通过Future.get()获取。而你需要的是持续的、多次的数值输出,Callable没法循环给你返回结果,所以用它自然达不到需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:29:20