通过接口从其他类修改MainActivity的TextView出现空指针异常如何解决
问题根因
核心错误出在Utils类中的static ICallback callback= new MainActivity();这行代码:
- 只有系统启动的Activity才会走完整生命周期,执行
onCreate、加载布局、初始化控件。你手动new出来的MainActivity是完全脱离系统管控的空实例,txtStatus等控件从未被初始化,关联的Context也是空值,所以会触发空指针错误。 - 静态持有Activity实例还会引发严重的内存泄漏,属于Android开发的典型错误写法。
- 额外隐藏问题:OkHttp的异步请求回调默认运行在子线程,直接在回调中更新UI也会导致崩溃。
可行修复方案
1. 重构Utils类
删除静态callback成员,改为方法入参传入回调,同时增加主线程切换逻辑:
public class Utils { // 删掉错误的静态callback声明 public static void downloadFile(String downloadURL, String fileName, ICallback callback) { IFileTransferClient client = ServiceGenerator.createService(IFileTransferClient.class); Call<ResponseBody> responseBodyCall = client.downloadFile(downloadURL); responseBodyCall.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { Log.d("MIHAI", "connection ok"); // 切回主线程更新UI new Handler(Looper.getMainLooper()).post(() -> { callback.setConnectionStatus("Connection successful"); }); } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { Log.d("MIHAI", "err...fail"); // 切回主线程更新UI new Handler(Looper.getMainLooper()).post(() -> { callback.setConnectionStatus("Connection failed. Check internet connection."); }); } }); } }
2. 修改MainActivity调用逻辑
调用downloadFile时传入当前活跃的Activity实例作为回调:
btnDownloadDB.setOnClickListener(v -> { txtStatus.setText(R.string.connecting); pb.setVisibility(View.VISIBLE); // 新增this参数,传入当前实现了ICallback的Activity实例 Utils.downloadFile(DOWNLOAD_DB, DB_FILE_NAME, this); });
可选优化(避免内存泄漏)
在回调方法中增加Activity存活判断,避免页面销毁后更新UI引发异常:
@Override public void setConnectionStatus(String status) { if (isFinishing() || isDestroyed()) { return; } Log.d("MIHAI", status); txtStatus.setText(status); }
内容的提问来源于stack exchange,提问作者Mihai Stanciu
相关产品推荐
相关产品推荐

