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

使用两个自定义接口对应不同AsyncTask的方案是否正确?无响应排查

你的AsyncTask回调方案分析与修复建议

首先得说:你的核心思路是对的——用自定义接口作为AsyncTask的回调来传递异步结果,并且针对上班/下班打卡分开定义接口,逻辑上是清晰合理的。但代码里有几个关键细节错误,导致你拿不到响应,下面帮你一一梳理并修复:

问题1:SharedPreferences操作时机错误

你在调用inTImeWorker.execute(emp_id)之后立刻就去读取In_time.getText()并存入SharedPreferences,但这时候AsyncTask还在后台执行网络请求,In_time的文本根本没更新!正确的时机应该是在回调方法里,也就是拿到异步结果并更新TextView之后再存。

问题2:未做非空判断,存在空指针风险

如果网络请求失败返回null,或者delegate没被正确赋值,直接调用delegate.ProcessFinish(result)会导致崩溃,必须加非空判断。

问题3:冗余代码(优化点)

两个AsyncTask的网络请求逻辑几乎完全重复,后续可以考虑抽象成工具类或基类,减少重复代码,但这不是当前问题的核心。


修复后的关键代码示例

1. 修改AsyncTask的onPostExecute方法(加非空判断)

InTImeWorker.java

@Override
protected void onPostExecute(String result) {
    // 先判断delegate和result都不为空,再执行回调
    if (delegate != null && result != null) {
        delegate.ProcessFinish(result);
    } else {
        // 可以在这里给用户提示网络请求失败
        alertDialog.setMessage("Failed to get in time data");
        alertDialog.show();
    }
}

OutTimeWorker.java

@Override
protected void onPostExecute(String result) {
    if (delegate != null && result != null) {
        delegate.ProcessFinishSecond(result);
    } else {
        alertDialog.setMessage("Failed to get out time data");
        alertDialog.show();
    }
}

2. 调整EmployeeActivity的回调与SharedPreferences逻辑

EmployeeActivity.java
首先修正OnAttendLogin方法,把SharedPreferences操作移到回调里:

public void OnAttendLogin(View view) {
    sp = getSharedPreferences("attendlogin", MODE_PRIVATE);
    String emp_id = sp.getString("emp_id", null);
    InTImeWorker inTImeWorker = new InTImeWorker(this);
    inTImeWorker.delegate = this; // 无需强制转型,Activity已实现接口
    inTImeWorker.execute(emp_id);
    
    // 先更新按钮状态,结果回调后再存数据
    out_time_button.setEnabled(true);
    in_time_button.setEnabled(false);
}

// 回调方法里更新TextView并存储数据
@Override
public void ProcessFinish(String Output) {
    In_time.setText(Output);
    // 现在才是正确的存储时机,因为已经拿到最新结果
    SharedPreferences sp1 = getSharedPreferences("InTime", MODE_PRIVATE);
    SharedPreferences.Editor editor1 = sp1.edit();
    editor1.putString("in_time_sp", Output);
    editor1.apply(); // apply()是异步提交,比commit()更推荐,无需同时调用两者
}

同理修正下班打卡的逻辑:

public void OnLogout(View view) {
    sp = getSharedPreferences("attendlogin", MODE_PRIVATE);
    String emp_id = sp.getString("emp_id", null);
    OutTimeWorker outTimeWorker = new OutTimeWorker(this);
    outTimeWorker.delegate = this;
    outTimeWorker.execute(emp_id);
    
    out_time_button.setEnabled(false);
    in_time_button.setEnabled(false);
}

@Override
public void ProcessFinishSecond(String Output) {
    Out_time.setText(Output);
    // 如果需要存储下班时间,在这里操作
    SharedPreferences spOut = getSharedPreferences("OutTime", MODE_PRIVATE);
    SharedPreferences.Editor editorOut = spOut.edit();
    editorOut.putString("out_time_sp", Output);
    editorOut.apply();
}

额外注意事项

  • 网络权限:确保AndroidManifest.xml中添加了网络权限:
    <uses-permission android:name="android.permission.INTERNET"/>
    
    没有这个权限的话,网络请求会直接失败,返回null。
  • AsyncTask过时提醒:Android 11之后AsyncTask已被标记为过时,新项目推荐用Kotlin协程、OkHttp+Coroutines或者WorkManager来处理异步任务,不过旧项目修复后仍可正常使用。
  • 异常提示:当前代码里的异常只做了printStackTrace,建议在网络请求失败时给用户弹出提示(比如上面代码里的AlertDialog),提升用户体验。

修复完这些点之后,你应该就能正常获取异步任务的结果并更新TextView了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:57:35