Android SDK 26下线程循环递增值的跨类回调问题求助
嘿,我来帮你搞定这个问题!你的场景是在Android SDK 26环境下,Class B内部启动了一个带while循环的线程,循环里递增整数并休眠X毫秒,现在想把每次递增后的数值反馈给其他类(比如初始化B的Class A),但B又不能依赖A的存在对吧?Callable确实不太适合这种持续输出结果的场景——它主要是给单次任务提供返回值的,咱们换几个更贴合需求的方案:
方案1:使用回调接口(最经典的解耦实现)
这是处理这类“单向通知”场景的标准做法,通过定义一个接口把B和接收方解耦,B只需要知道要调用这个接口的方法,不用关心具体是谁实现它。
步骤示例:
- 先定义一个回调接口,用来传递数值:
public interface OnCountUpdateListener { void onCountUpdated(int currentCount); }
- 在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(); } } }
- 在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是更好的选择——它能自动感知组件生命周期,避免内存泄漏,还能在组件活跃时才接收更新。
步骤示例:
- 在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(); } } }
- 在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
相关产品推荐
相关产品推荐

