Java如何从Runnable线程获取返回值:NewImage类方法无法获取结果问题
问题根因
你当前的fct_2完全拿不到执行结果的核心原因是:方法内部启动新线程时没有做任何结果等待、回传逻辑。
当你调用fct_2()时,new Thread(...)只是触发了异步线程的启动流程,方法本身会立刻执行完毕,既不会等待内部Runnable块里的code 2执行完成,也没有任何返回值会把code 2生成的Bitmap带出来——甚至你现在写的fct_2因为没有匹配返回值的return语句,本身就无法正常编译。哪怕你临时给方法加个return null的语句,最终拿到的received也永远是空值,根本不是后台线程实际生成的结果。
可落地的解决方法
根据你的使用场景不同,常用的实现方式有两种:
场景1:在工作线程中调用fct_2,允许短暂阻塞拿结果
这种场景下不需要考虑主线程卡死的问题,可以直接用带返回值的任务替换无返回值的Runnable,同步等待线程执行完成拿结果:
public static Bitmap fct_2() throws Exception { // 用Callable定义有返回值的任务块 Callable<Bitmap> bitmapTask = () -> { // 这里替换成原有的code 2 逻辑,最后返回生成的Bitmap即可 return generatedBitmap; }; FutureTask<Bitmap> future = new FutureTask<>(bitmapTask); // 启动线程执行任务 new Thread(future).start(); // 阻塞等待线程执行完成,拿到任务的返回值 return future.get(); }
*注意:这种写法会阻塞当前调用fct_2的线程,绝对不能在安卓主线程中直接调用,否则会因为主线程阻塞触发应用无响应(ANR)问题。
场景2:在安卓主线程/UI线程中调用fct_2,需要拿结果刷新界面
这种场景不能阻塞主线程,所以不要再硬要求方法有同步返回值,改用回调机制把后台执行的结果异步传出来:
- 先在
NewImage类中定义结果回调接口:
public interface BitmapCallback { // 后台执行成功拿到结果时触发 void onResult(Bitmap result); // 后台执行出错时触发 void onError(Exception e); }
- 改造
fct_2的方法签名,去掉返回值,加入回调参数:
public static void fct_2(BitmapCallback callback) { new Thread(() -> { try { // 放原有的code 2 逻辑,生成目标Bitmap Bitmap generatedBitmap = ...; // 切回主线程回调结果,避免直接在子线程操作UI new Handler(Looper.getMainLooper()).post(() -> { callback.onResult(generatedBitmap); }); } catch (Exception e) { new Handler(Looper.getMainLooper()).post(() -> { callback.onError(e); }); } }).start(); }
- 调用时不要再用同步赋值的方式拿结果,而是在回调中处理收到的Bitmap:
NewImage_1.fct_2(new BitmapCallback() { @Override public void onResult(Bitmap result) { // 这里拿到的result就是后台线程生成的Bitmap,可以直接赋值、刷新UI received = result; // 比如给ImageView设置图片 imageView.setImageBitmap(received); } @Override public void onError(Exception e) { // 处理异常逻辑 } });
内容的提问来源于stack exchange,提问作者Ra ben
相关产品推荐
相关产品推荐

