Android AsyncTask调用异常:HashMap值被覆盖致请求参数错误
问题分析与解决方案
这个问题我太熟了!咱们来一步步拆解和解决它~
你遇到的核心问题是复用了同一个HashMap对象,再加上循环里的变量引用细节没处理好,导致两次AsyncTask最终都拿到了最后一次设置的package_id值。
为什么会出现覆盖?
Java里对象是引用传递的:你在循环外创建了data_pkg_act这个HashMap,每次循环只是往同一个map里覆盖package_id的键值对。哪怕你用execute().get()同步等待任务完成,两次AsyncTask持有的都是同一个HashMap的引用——当第二次循环修改map时,第一次任务读取的也是这个map的最新值,最后自然两次都拿到了package_id=2。
另外注意:原代码里循环条件写的是pk_id.length,应该是笔误,实际要遍历的是pkg_id数组对吧?
方案1:每次循环创建独立的HashMap
把HashMap的创建逻辑移到循环内部,让每个AsyncTask都持有属于自己的独立map,彻底避免覆盖问题:
String[] pkg_id = new String[]{"1", "2"}; // 假设这里是正确的多元素数组 Log.d("pkg_id","=>"+Arrays.toString(pkg_id)); for(int k=0;k<pkg_id.length;k++) { String currentPkgId = pkg_id[k]; // 先缓存当前循环的package_id,避免引用混淆 Log.d("pkg_id","==>"+currentPkgId); try { // 每次循环新建HashMap HashMap<String,String> data_pkg_act = new HashMap<>(); data_pkg_act.put("package_id", currentPkgId); new GetPackageDetails(data_pkg_act).execute().get(); } catch (InterruptedException | ExecutionException e) { // 注意:execute().get()还会抛出ExecutionException,别漏了捕获 e.printStackTrace(); } }
方案2:直接传递String参数给AsyncTask(更简洁)
既然你只需要传递package_id这一个参数,完全没必要用HashMap。直接修改GetPackageDetails的构造方法,让它接收String类型的参数,代码会更清晰,也从根源避免了map覆盖的问题:
// 先修改你的AsyncTask类 class GetPackageDetails extends AsyncTask<Void, Void, YourResultType> { private String packageId; // 构造方法直接接收package_id public GetPackageDetails(String packageId) { this.packageId = packageId; } @Override protected YourResultType doInBackground(Void... voids) { // 在这里直接使用this.packageId即可,不用再从HashMap取值 // 示例:调用接口时传入packageId return yourApiCall(this.packageId); } // 其他重写方法(比如onPostExecute)... } // 然后修改循环代码 String[] pkg_id = new String[]{"1", "2"}; Log.d("pkg_id","=>"+Arrays.toString(pkg_id)); for(int k=0;k<pkg_id.length;k++) { String currentPkgId = pkg_id[k]; Log.d("pkg_id","==>"+currentPkgId); try { new GetPackageDetails(currentPkgId).execute().get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } }
额外小提醒
原代码里pkg_id数组的初始化是new String[]{package_id},如果package_id是一个拼接字符串(比如"1,2"),那这个数组其实只有一个元素,你需要先分割它才能实现两次循环。不过从你的日志来看循环执行了两次,所以应该是pkg_id本身就是多元素数组,这里注意检查哦~
内容的提问来源于stack exchange,提问作者Prashant
相关产品推荐
相关产品推荐

