修复实时距离显示问题

This commit is contained in:
ZhanGSKen
2025-10-01 02:14:10 +08:00
parent f5b2500f06
commit 80424c523d
4 changed files with 766 additions and 745 deletions

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Tue Sep 30 13:02:23 GMT 2025
#Tue Sep 30 18:06:22 GMT 2025
stageCount=4
libraryProject=
baseVersion=15.0
publishVersion=15.0.3
buildCount=9
buildCount=10
baseBetaVersion=15.0.4

View File

@@ -9,6 +9,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.view.LayoutInflater;
@@ -53,9 +54,9 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
private static final int DEFAULT_TASK_DISTANCE = 100;
// 核心成员变量Java7明确泛型声明与初始化
private final ArrayList<PositionModel> mPositionList;
private final ArrayList<PositionModel> mPositionList; // 数据源与Service共享同一份引用
private final ArrayList<PositionTaskModel> mAllPositionTasks;
private final Context mContext;
private Context mContext;
private PositionModel mCurrentGpsPosition;
private final Map<String, ArrayList<PositionTaskModel>> mPositionTaskMap;
private final Map<String, TextView> mVisibleDistanceViews = new HashMap<String, TextView>();
@@ -73,13 +74,13 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
mDistanceService = binder.getService();
isServiceBound = true;
// 绑定服务后初始化:设置接收器+同步数据
// 绑定服务后初始化:设置接收器+同步数据传递mPositionList原引用
mDistanceService.setOnDistanceUpdateReceiver(PositionAdapter.this);
mDistanceService.syncPositionList(mPositionList);
mDistanceService.syncPositionList(mPositionList); // 关键:传递原列表引用
mDistanceService.syncAllPositionTasks(mAllPositionTasks);
mDistanceService.syncCurrentGpsPosition(mCurrentGpsPosition);
// 同步已有的可见控件(解决“控件已添加但服务未收到”问题)
// 同步已有的可见控件
Iterator<String> posIdIterator = mVisibleDistanceViews.keySet().iterator();
while (posIdIterator.hasNext()) {
String positionId = posIdIterator.next();
@@ -89,7 +90,6 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
LogUtils.d(TAG, "DistanceRefreshService 绑定成功");
}
@Override
public void onServiceDisconnected(ComponentName name) {
mDistanceService = null;
@@ -116,23 +116,23 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
private OnSavePositionTaskClickListener mOnSavePositionTaskClickListener;
// 构造函数Java7明确泛型非空判断初始化
public PositionAdapter(Context context, ArrayList<PositionModel> positionList, ArrayList<PositionTaskModel> allPositionTasks) {
public PositionAdapter(Context context, ArrayList positionList, ArrayList allPositionTasks) {
this.mContext = context;
// Java7显式非空判断避免空指针
this.mPositionList = (positionList != null) ? positionList : new ArrayList<PositionModel>();
this.mAllPositionTasks = (allPositionTasks != null) ? allPositionTasks : new ArrayList<PositionTaskModel>();
this.mPositionList = (positionList != null) ? positionList : new ArrayList();
this.mAllPositionTasks = (allPositionTasks != null) ? allPositionTasks : new ArrayList();
this.mPositionTaskMap = new HashMap<String, ArrayList<PositionTaskModel>>();
// 初始化任务映射表Java7双迭代器遍历
Iterator<PositionModel> modelIterator = mPositionList.iterator();
Iterator modelIterator = mPositionList.iterator();
while (modelIterator.hasNext()) {
PositionModel model = modelIterator.next();
PositionModel model = (PositionModel)modelIterator.next();
String validPosId = model.getPositionId();
ArrayList<PositionTaskModel> matchedTasks = new ArrayList<PositionTaskModel>();
ArrayList matchedTasks = new ArrayList();
Iterator<PositionTaskModel> taskIterator = this.mAllPositionTasks.iterator();
Iterator taskIterator = this.mAllPositionTasks.iterator();
while (taskIterator.hasNext()) {
PositionTaskModel task = taskIterator.next();
PositionTaskModel task = (PositionTaskModel)taskIterator.next();
if (task != null && validPosId.equals(task.getPositionId())) {
matchedTasks.add(task);
}
@@ -193,45 +193,77 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
mVisibleDistanceViews.clear();
}
// ---------------------- 服务消息接收(距离更新 ----------------------
// ---------------------- 服务消息接收(仅接收位置ID从mPositionList读数据 ----------------------
@Override
public void onDistanceUpdate(final String positionId, final String distanceText, final int distanceColor) {
// 保障主线程更新Java7匿名内部类实现Runnable替代Lambda
public void onDistanceUpdate(final String positionId) {
// 保障主线程更新UIJava7匿名内部类实现Runnable
if (Looper.myLooper() != Looper.getMainLooper()) {
mUiHandler.post(new Runnable() {
@Override
public void run() {
updateDistanceView(positionId, distanceText, distanceColor);
updateDistanceViewByPositionId(positionId);
}
});
} else {
updateDistanceView(positionId, distanceText, distanceColor);
updateDistanceViewByPositionId(positionId);
}
}
/**
* 精准更新距离TextViewJava7显式非空判断避免空指针
*/
private void updateDistanceView(String positionId, String distanceText, int distanceColor) {
// 1. 检查核心参数(避免无效更新)
if (positionId == null || distanceText == null || mVisibleDistanceViews.isEmpty()) {
LogUtils.w(TAG, "更新距离失败参数无效位置ID=" + positionId + ",距离文本=" + distanceText + "");
return;
}
// 2. 找到目标TextView并更新
- 核心修改通过位置ID从mPositionList读取realPositionDistance生成UI数据并更新
*/
private void updateDistanceViewByPositionId(String positionId) {
// 1. 前置校验(避免无效更新)
if (positionId == null || mPositionList.isEmpty() || mVisibleDistanceViews.isEmpty()) {
LogUtils.w(TAG, "更新UI失败参数无效/列表为空位置ID=" + positionId + "");
return;
}// 2. 从mPositionList找到对应位置模型Java7迭代器遍历
PositionModel targetModel = null;
Iterator modelIter = mPositionList.iterator();
while (modelIter.hasNext()) {
PositionModel model = (PositionModel)modelIter.next();
if (positionId.equals(model.getPositionId())) {
targetModel = model;
break;
}
}
if (targetModel == null) {
LogUtils.w(TAG, "更新UI失败位置ID=" + positionId + " 未找到对应模型");
return;
}// 3. 读取realPositionDistance生成距离文本和颜色
double distanceM = targetModel.getRealPositionDistance();
String distanceText;
int distanceColor;if (distanceM == -1) {
// 距离为-1区分“未启用”和“计算异常”
if (targetModel.isEnableRealPositionDistance()) {
distanceText = "实时距离:计算异常";
distanceColor = getColorRes(R.color.colorRed);
} else {
distanceText = "实时距离:未启用";
distanceColor = getColorRes(R.color.colorGrayText);
}
} else {
// 距离有效:格式化显示(米/千米)
if (distanceM < 1000) {
distanceText = String.format("实时距离:%.1f 米", distanceM);
} else {
distanceText = String.format("实时距离:%.1f 千米", distanceM / 1000);
}
distanceColor = getColorRes(R.color.colorEnableGreen);
}// 4. 刷新可见控件(仅更新屏幕上显示的控件)
TextView distanceView = mVisibleDistanceViews.get(positionId);
if (distanceView != null && distanceView.isShown()) { // 仅更新“显示中”的控件
LogUtils.d(TAG, "更新距离UI位置ID=" + positionId + ",文本=" + distanceText);
if (distanceView != null && distanceView.isShown()) {
distanceView.setText(distanceText);
distanceView.setTextColor(distanceColor);
// 同步更新任务状态
LogUtils.d(TAG, "更新UI成功位置ID=" + positionId + ",文本=" + distanceText);
// 同步刷新任务状态(原逻辑保留)
refreshTaskBingoStatus(positionId);
} else {
// 控件不存在/不可见时,移除映射+同步服务
// 控件不存在/不可见:清理映射+同步服务
if (mVisibleDistanceViews.containsKey(positionId)) {
mVisibleDistanceViews.remove(positionId);
LogUtils.w(TAG, "更新距离失败位置ID=" + positionId + " 对应的TextView不存在/已移除");
LogUtils.w(TAG, "更新UI失败位置ID=" + positionId + " 控件不可见/已移除");
}
if (isServiceBound && mDistanceService != null) {
mDistanceService.removeVisibleDistanceView(positionId);
@@ -239,21 +271,24 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
}
}
/**
- 保留:从上下文获取颜色资源(异常时返回默认灰色)
*/
@Override
public int getColorRes(int resId) {
if (mContext != null) {
try {
// Java7显式调用getResources(),避免空指针
return mContext.getResources().getColor(resId);
} catch (Exception e) {
LogUtils.d(TAG, "获取颜色资源失败resId=" + resId + "" + e.getMessage());
return mContext.getResources().getColor(R.color.colorGrayText); // 异常时返回默认灰色
return mContext.getResources().getColor(R.color.colorGrayText);
}
}
return mContext.getResources().getColor(R.color.colorGrayText);
}
// ---------------------- 任务状态刷新 ----------------------
// ---------------------- 任务状态刷新(原逻辑保留) ----------------------
private void refreshTaskBingoStatus(String positionId) {
Integer targetPosIndex = mPositionIdToIndexMap.get(positionId);
if (targetPosIndex != null && targetPosIndex >= 0 && targetPosIndex < mPositionList.size()) {
@@ -262,13 +297,12 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
}
}
// ---------------------- RecyclerView 核心方法 ----------------------
// ---------------------- RecyclerView 核心方法(原逻辑保留,适配数据来源) ----------------------
@Override
public int getItemViewType(int position) {
// Java7显式非空+范围判断(避免越界)
if (position < 0 || position >= mPositionList.size()) {
LogUtils.w(TAG, "getItemViewType无效列表位置position=" + position + "");
return VIEW_TYPE_SIMPLE; // 异常时返回默认类型
return VIEW_TYPE_SIMPLE;
}
PositionModel model = mPositionList.get(position);
return model.isSimpleView() ? VIEW_TYPE_SIMPLE : VIEW_TYPE_EDIT;
@@ -289,7 +323,6 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
// Java7显式范围判断避免越界
if (position < 0 || position >= mPositionList.size()) {
LogUtils.w(TAG, "onBindViewHolder无效列表位置position=" + position + "");
return;
@@ -297,7 +330,6 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
PositionModel model = mPositionList.get(position);
mPositionIdToIndexMap.put(model.getPositionId(), position);
// 绑定对应视图
if (holder instanceof SimpleViewHolder) {
bindSimpleView((SimpleViewHolder) holder, model, position);
} else if (holder instanceof EditViewHolder) {
@@ -310,7 +342,7 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
return mPositionList.size();
}
// ---------------------- 视图附加/分离/回收(控件管理 ----------------------
// ---------------------- 视图附加/分离/回收(原逻辑保留,优化性能 ----------------------
@Override
public void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder holder) {
super.onViewAttachedToWindow(holder);
@@ -322,9 +354,9 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
PositionModel model = mPositionList.get(position);
String positionId = model.getPositionId();
mPositionIdToIndexMap.put(positionId, position); // 同步索引
mPositionIdToIndexMap.put(positionId, position);
// 找到距离TextViewJava7显式类型转换+非空判断
// 找到距离TextViewJava7显式类型转换
TextView distanceView = null;
if (holder instanceof SimpleViewHolder) {
distanceView = ((SimpleViewHolder) holder).tvSimpleRealDistance;
@@ -332,15 +364,12 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
distanceView = ((EditViewHolder) holder).tvEditRealDistance;
}
// 添加有效控件,避免重复映射
// 添加可见控件映射(避免重复
if (distanceView != null && !mVisibleDistanceViews.containsKey(positionId)) {
mVisibleDistanceViews.put(positionId, distanceView);
LogUtils.d(TAG, "视图附加添加可见控件位置ID=" + positionId + "当前可见数量=" + mVisibleDistanceViews.size());
// 同步到服务
LogUtils.d(TAG, "视图附加添加可见控件位置ID=" + positionId + "),数量=" + mVisibleDistanceViews.size());
if (isServiceBound && mDistanceService != null) {
mDistanceService.addVisibleDistanceView(positionId);
} else {
LogUtils.w(TAG, "视图附加服务未绑定暂未同步控件位置ID=" + positionId + "");
}
}
}
@@ -356,10 +385,10 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
PositionModel model = mPositionList.get(position);
String positionId = model.getPositionId();
// 移除本地映射+同步服务
// 移除可见控件映射
if (mVisibleDistanceViews.containsKey(positionId)) {
mVisibleDistanceViews.remove(positionId);
LogUtils.d(TAG, "视图分离移除可见控件位置ID=" + positionId + "当前可见数量=" + mVisibleDistanceViews.size());
LogUtils.d(TAG, "视图分离移除可见控件位置ID=" + positionId + "),数量=" + mVisibleDistanceViews.size());
if (isServiceBound && mDistanceService != null) {
mDistanceService.removeVisibleDistanceView(positionId);
}
@@ -372,17 +401,16 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
int position = holder.getAdapterPosition();
if (position >= 0 && position < mPositionList.size()) {
String positionId = mPositionList.get(position).getPositionId();
// 清理本地映射
// 清理映射
mVisibleDistanceViews.remove(positionId);
mPositionIdToIndexMap.remove(positionId);
LogUtils.d(TAG, "视图回收清理控件映射位置ID=" + positionId + "");
// 同步服务
if (isServiceBound && mDistanceService != null) {
mDistanceService.removeVisibleDistanceView(positionId);
}
}
// 清理任务列表资源Java7显式非空判断
// 清理任务列表资源
if (holder instanceof SimpleViewHolder) {
SimpleViewHolder simpleHolder = (SimpleViewHolder) holder;
if (simpleHolder.ptlvSimpleTasks != null) {
@@ -398,30 +426,34 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
}
}
// ---------------------- 视图绑定(简单视图/编辑视图) ----------------------
// ---------------------- 视图绑定(简单视图/编辑视图,原逻辑保留 ----------------------
/**
* 绑定简单视图(仅展示,无编辑功能)
- 绑定简单视图(仅展示)
*/
private void bindSimpleView(final SimpleViewHolder holder, final PositionModel model, final int position) {
// 绑定基础数据(Java7显式String.format避免自动类型转换
// 绑定基础数据(保留6位小数
holder.tvSimpleLongitude.setText(String.format("经度:%.6f", model.getLongitude()));
holder.tvSimpleLatitude.setText(String.format("纬度:%.6f", model.getLatitude()));
holder.tvSimpleMemo.setText(String.format("备注:%s", model.getMemo()));
// 初始默认文本(记录日志,便于排查未覆盖问题)
holder.tvSimpleRealDistance.setText("实时距离:加载中...");
holder.tvSimpleRealDistance.setTextColor(mContext.getResources().getColor(R.color.colorGrayText));
LogUtils.d(TAG, "绑定简单视图初始化距离文本位置ID=" + model.getPositionId() + "");
// 长按编辑逻辑Java7匿名内部类实现OnLongClickListener+PopupMenu监听
holder.tvSimpleMemo.setText(String.format("备注:%s", model.getMemo()));// 初始化距离文本从mPositionList读realPositionDistance
double initDistance = model.getRealPositionDistance();
if (initDistance == -1) {
holder.tvSimpleRealDistance.setText(model.isEnableRealPositionDistance() ? "实时距离:计算异常" : "实时距离:未启用");
holder.tvSimpleRealDistance.setTextColor(getColorRes(model.isEnableRealPositionDistance() ? R.color.colorRed : R.color.colorGrayText));
} else {
String initText = initDistance < 1000 ?
String.format("实时距离:%.1f 米", initDistance) :
String.format("实时距离:%.1f 千米", initDistance / 1000);
holder.tvSimpleRealDistance.setText(initText);
holder.tvSimpleRealDistance.setTextColor(getColorRes(R.color.colorEnableGreen));
}
LogUtils.d(TAG, "绑定简单视图初始化距离位置ID=" + model.getPositionId() + "");// 长按编辑逻辑(匿名内部类)
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
PopupMenu popupMenu = new PopupMenu(mContext, v);
MenuInflater menuInflater = popupMenu.getMenuInflater();
menuInflater.inflate(R.menu.menu_item_edit, popupMenu.getMenu());
// Java7匿名内部类实现PopupMenu监听
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
menuInflater.inflate(R.menu.menu_item_edit, popupMenu.getMenu());popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == R.id.menu_edit) {
@@ -435,11 +467,9 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
popupMenu.show();
return true;
}
});
// 绑定任务列表Java7显式获取安全任务列表
});// 绑定任务列表
String currentPosId = model.getPositionId();
ArrayList<PositionTaskModel> matchedTasks = getSafeTasks(currentPosId);
ArrayList matchedTasks = getSafeTasks(currentPosId);
if (holder.ptlvSimpleTasks != null) {
holder.ptlvSimpleTasks.clearData();
holder.ptlvSimpleTasks.setViewStatus(PositionTaskListView.VIEW_MODE_SIMPLE);
@@ -450,27 +480,36 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
}
/**
* 绑定编辑视图(支持修改备注、开关距离、增删任务)
- 绑定编辑视图(支持修改)
*/
private void bindEditView(final EditViewHolder holder, final PositionModel model, final int position) {
// 绑定基础数据
holder.tvEditLongitude.setText(String.format("经度:%.6f", model.getLongitude()));
holder.tvEditLatitude.setText(String.format("纬度:%.6f", model.getLatitude()));
holder.etEditMemo.setText(model.getMemo());
holder.etEditMemo.setSelection(holder.etEditMemo.getText().length());
// 初始默认文本
holder.tvEditRealDistance.setText("实时距离:加载中...");
holder.tvEditRealDistance.setTextColor(mContext.getResources().getColor(R.color.colorGrayText));
LogUtils.d(TAG, "绑定编辑视图初始化距离文本位置ID=" + model.getPositionId() + "");
holder.etEditMemo.setSelection(holder.etEditMemo.getText().length());// 初始化距离文本从mPositionList读realPositionDistance
double initDistance = model.getRealPositionDistance();
if (initDistance == -1) {
holder.tvEditRealDistance.setText(model.isEnableRealPositionDistance() ? "实时距离:计算异常" : "实时距离:未启用");
holder.tvEditRealDistance.setTextColor(getColorRes(model.isEnableRealPositionDistance() ? R.color.colorRed : R.color.colorGrayText));
} else {
String initText = initDistance < 1000 ?
String.format("实时距离:%.1f 米", initDistance) :
String.format("实时距离:%.1f 千米", initDistance / 1000);
holder.tvEditRealDistance.setText(initText);
holder.tvEditRealDistance.setTextColor(getColorRes(R.color.colorEnableGreen));
}
LogUtils.d(TAG, "绑定编辑视图初始化距离位置ID=" + model.getPositionId() + "");
// 实时距离开关状态(Java7显式判断设置选中)
// 实时距离开关状态(显式判断设置选中)
if (model.isEnableRealPositionDistance()) {
holder.rgRealDistanceSwitch.check(R.id.rb_enable);
} else {
holder.rgRealDistanceSwitch.check(R.id.rb_disable);
}
// 删除按钮逻辑(Java7匿名内部类实现OnClickListener
// 删除按钮逻辑(匿名内部类
holder.btnEditDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -479,9 +518,10 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
// 清理本地映射
mPositionTaskMap.remove(model.getPositionId());
mPositionIdToIndexMap.remove(model.getPositionId());
// 同步服务
// 同步服务(移除无效位置)
if (isServiceBound && mDistanceService != null) {
mDistanceService.removeVisibleDistanceView(model.getPositionId());
mDistanceService.syncPositionList(mPositionList); // 同步更新后的列表
}
}
}
@@ -501,7 +541,7 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
holder.btnEditConfirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 获取输入数据(Java7显式trim避免空字符串)
// 获取输入数据显式trim避免空字符串
String newMemo = holder.etEditMemo.getText().toString().trim();
model.setMemo(newMemo);
boolean isEnableDistance = holder.rgRealDistanceSwitch.getCheckedRadioButtonId() == R.id.rb_enable;
@@ -509,13 +549,13 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
// 绑定任务到当前位置
String currentPosId = model.getPositionId();
ArrayList<PositionTaskModel> allTasks = (holder.ptlvEditTasks != null) ? holder.ptlvEditTasks.getAllTasks() : new ArrayList<PositionTaskModel>();
ArrayList<PositionTaskModel> boundTasks = new ArrayList<PositionTaskModel>();
ArrayList allTasks = (holder.ptlvEditTasks != null) ? holder.ptlvEditTasks.getAllTasks() : new ArrayList();
ArrayList boundTasks = new ArrayList();
// Java7迭代器遍历任务列表绑定位置ID
Iterator<PositionTaskModel> taskIterator = allTasks.iterator();
// 迭代器遍历:绑定位置ID到任务
Iterator taskIterator = allTasks.iterator();
while (taskIterator.hasNext()) {
PositionTaskModel task = taskIterator.next();
PositionTaskModel task = (PositionTaskModel)taskIterator.next();
if (task != null) {
task.setPositionId(currentPosId);
boundTasks.add(task);
@@ -524,21 +564,21 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
// 更新本地任务映射
mPositionTaskMap.put(currentPosId, boundTasks);
// 清理旧任务+添加新任务Java7迭代器删除,避免ConcurrentModificationException
Iterator<PositionTaskModel> globalTaskIter = mAllPositionTasks.iterator();
// 清理旧任务迭代器安全删除,避免并发异常
Iterator globalTaskIter = mAllPositionTasks.iterator();
while (globalTaskIter.hasNext()) {
PositionTaskModel task = globalTaskIter.next();
PositionTaskModel task = (PositionTaskModel)globalTaskIter.next();
if (task != null && currentPosId.equals(task.getPositionId())) {
globalTaskIter.remove(); // Java7迭代器安全删除
globalTaskIter.remove();
}
}
mAllPositionTasks.addAll(boundTasks);
// 同步服务数据
// 同步服务数据(传递原列表引用)
if (isServiceBound && mDistanceService != null) {
mDistanceService.syncPositionList(mPositionList);
mDistanceService.syncAllPositionTasks(mAllPositionTasks);
LogUtils.d(TAG, "编辑视图保存:同步位置+任务数据到服务位置ID=" + currentPosId + "");
mDistanceService.syncPositionList(mPositionList); // 同步更新后的位置列表
mDistanceService.syncAllPositionTasks(mAllPositionTasks); // 同步更新后的任务列表
LogUtils.d(TAG, "编辑保存:同步位置+任务到服务位置ID=" + currentPosId + "");
}
// 切换视图+回调通知
@@ -551,21 +591,21 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
}
});
// 任务列表绑定与更新逻辑(Java7匿名内部类实现任务更新监听)
// 任务列表绑定与更新逻辑(匿名内部类实现监听)
final String currentPosId = model.getPositionId();
ArrayList<PositionTaskModel> matchedTasks = getSafeTasks(currentPosId);
ArrayList matchedTasks = getSafeTasks(currentPosId);
if (holder.ptlvEditTasks != null) {
holder.ptlvEditTasks.clearData();
// 任务更新监听Java7匿名内部类实现
// 任务更新监听
holder.ptlvEditTasks.setOnTaskUpdatedListener(new PositionTaskListView.OnTaskUpdatedListener() {
@Override
public void onTaskUpdated(String posId, ArrayList<PositionTaskModel> updatedTasks) {
ArrayList<PositionTaskModel> boundTasks = new ArrayList<PositionTaskModel>();
// 绑定任务到当前位置
Iterator<PositionTaskModel> taskIterator = updatedTasks.iterator();
public void onTaskUpdated(String posId, ArrayList updatedTasks) {
ArrayList boundTasks = new ArrayList();
// 绑定位置ID到任务
Iterator taskIterator = updatedTasks.iterator();
while (taskIterator.hasNext()) {
PositionTaskModel task = taskIterator.next();
PositionTaskModel task = (PositionTaskModel)taskIterator.next();
if (task != null) {
task.setPositionId(currentPosId);
boundTasks.add(task);
@@ -575,9 +615,9 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
// 更新本地映射
mPositionTaskMap.put(currentPosId, boundTasks);
// 清理旧任务+添加新任务
Iterator<PositionTaskModel> globalTaskIter = mAllPositionTasks.iterator();
Iterator globalTaskIter = mAllPositionTasks.iterator();
while (globalTaskIter.hasNext()) {
PositionTaskModel task = globalTaskIter.next();
PositionTaskModel task = (PositionTaskModel)globalTaskIter.next();
if (task != null && currentPosId.equals(task.getPositionId())) {
globalTaskIter.remove();
}
@@ -587,7 +627,7 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
// 同步服务
if (isServiceBound && mDistanceService != null) {
mDistanceService.syncAllPositionTasks(mAllPositionTasks);
LogUtils.d(TAG, "任务更新:同步任务数据到服务位置ID=" + currentPosId + ",任务数=" + boundTasks.size() + "");
LogUtils.d(TAG, "任务更新同步到服务位置ID=" + currentPosId + ",任务数=" + boundTasks.size() + "");
}
// 回调通知
@@ -605,7 +645,7 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
holder.ptlvEditTasks.setViewStatus(PositionTaskListView.VIEW_MODE_EDIT);
}
// 添加任务逻辑(Java7匿名内部类实现OnClickListener
// 添加任务逻辑(匿名内部类
holder.btnAddTask.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -615,7 +655,7 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
return;
}
// 创建新任务(Java7显式调用构造函数避免Builder模式
// 创建新任务(显式调用构造函数)
PositionTaskModel newTask = new PositionTaskModel(
PositionTaskModel.genTaskId(),
currentPosId,
@@ -626,15 +666,15 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
);
// 更新本地任务列表
ArrayList<PositionTaskModel> currentTasks = getSafeTasks(currentPosId);
ArrayList currentTasks = getSafeTasks(currentPosId);
currentTasks.add(newTask);
mPositionTaskMap.put(currentPosId, new ArrayList<PositionTaskModel>(currentTasks));
mPositionTaskMap.put(currentPosId, new ArrayList(currentTasks));
mAllPositionTasks.add(newTask);
// 同步服务
if (isServiceBound && mDistanceService != null) {
mDistanceService.syncAllPositionTasks(mAllPositionTasks);
LogUtils.d(TAG, "新增任务:同步任务数据到服务位置ID=" + currentPosId + "任务ID=" + newTask.getTaskId() + "");
LogUtils.d(TAG, "新增任务同步到服务位置ID=" + currentPosId + "任务ID=" + newTask.getTaskId() + "");
}
// 刷新任务列表视图
@@ -646,208 +686,177 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
});
}
// ---------------------- 工具方法 ----------------------
// ---------------------- 工具方法(原逻辑保留,适配数据来源) ----------------------
/**
* 安全获取任务列表避免空指针Java7显式泛型
- 安全获取任务列表(避免空指针)
*/
private ArrayList<PositionTaskModel> getSafeTasks(String positionId) {
private ArrayList getSafeTasks(String positionId) {
if (positionId == null) {
LogUtils.w(TAG, "getSafeTasks位置ID为空返回空任务列表");
return new ArrayList<PositionTaskModel>();
LogUtils.w(TAG, "getSafeTasks位置ID为空返回空列表");
return new ArrayList();
}
if (!mPositionTaskMap.containsKey(positionId)) {
mPositionTaskMap.put(positionId, new ArrayList<PositionTaskModel>());
LogUtils.d(TAG, "getSafeTasks位置ID=" + positionId + " 无任务列表,初始化空列表");
mPositionTaskMap.put(positionId, new ArrayList());
LogUtils.d(TAG, "getSafeTasks初始化空任务列表(位置ID=" + positionId + "");
}
return mPositionTaskMap.get(positionId);
}
/**
* 新增位置Java7显式非空判断迭代器同步索引
- 新增位置(同步服务时传递原列表引用)
*/
public void addPosition(PositionModel model) {
if (model == null || model.getPositionId() == null) {
LogUtils.e(TAG, "新增位置失败:位置模型/位置ID为空");
LogUtils.e(TAG, "新增位置失败:模型/位置ID为空");
return;
}
String validPosId = model.getPositionId();
mPositionList.add(model);
mPositionIdToIndexMap.put(validPosId, mPositionList.size() - 1);
// 初始化任务列表(若不存在)
mPositionIdToIndexMap.put(validPosId, mPositionList.size() - 1);// 初始化任务列表(若不存在)
if (!mPositionTaskMap.containsKey(validPosId)) {
mPositionTaskMap.put(validPosId, new ArrayList<PositionTaskModel>());
}
// 同步服务+刷新视图
mPositionTaskMap.put(validPosId, new ArrayList());
}// 同步服务(传递原列表引用)
if (isServiceBound && mDistanceService != null) {
mDistanceService.syncPositionList(mPositionList);
// 若控件已添加,立即同步服务
mDistanceService.syncPositionList(mPositionList); // 同步更新后的列表
if (mVisibleDistanceViews.containsKey(validPosId)) {
mDistanceService.addVisibleDistanceView(validPosId);
LogUtils.d(TAG, "新增位置同步服务并添加控件位置ID=" + validPosId + "");
}
}
notifyItemInserted(mPositionList.size() - 1);
LogUtils.d(TAG, "新增位置成功位置ID=" + validPosId + ",当前列表总数=" + mPositionList.size());
LogUtils.d(TAG, "新增位置同步到服务位置ID=" + validPosId + ",列表总数=" + mPositionList.size() + "");
}notifyItemInserted(mPositionList.size() - 1);
}
/**
* 删除位置Java7迭代器安全删除避免并发异常
- 删除位置(同步服务时传递更新后的列表)
*/
public void removePosition(int position) {
if (position < 0 || position >= mPositionList.size()) {
LogUtils.w(TAG, "删除位置失败:无效列表位置position=" + position + "");
LogUtils.w(TAG, "删除位置失败:无效索引position=" + position + "");
return;
}
PositionModel removedModel = mPositionList.get(position);
String removedPosId = removedModel.getPositionId();
if (removedPosId == null) {
LogUtils.w(TAG, "删除位置失败:待删除位置ID为空列表位置=" + position + "");
LogUtils.w(TAG, "删除位置失败位置ID为空索引=" + position + "");
return;
}
// 1. 清理本地缓存和映射
}// 1. 清理本地映射
mVisibleDistanceViews.remove(removedPosId);
mPositionIdToIndexMap.remove(removedPosId);
LogUtils.d(TAG, "删除位置清理本地映射位置ID=" + removedPosId + "");
// 2. 重新同步剩余位置的索引映射Java7迭代器遍历
Iterator<PositionModel> modelIterator = mPositionList.iterator();
LogUtils.d(TAG, "删除位置清理本地映射位置ID=" + removedPosId + "");// 2. 重新同步剩余位置的索引
Iterator modelIterator = mPositionList.iterator();
int index = 0;
while (modelIterator.hasNext()) {
PositionModel remainingModel = modelIterator.next();
PositionModel remainingModel = (PositionModel)modelIterator.next();
mPositionIdToIndexMap.put(remainingModel.getPositionId(), index);
index++;
}
// 3. 清理全局任务列表和映射表Java7迭代器安全删除
Iterator<PositionTaskModel> taskIterator = mAllPositionTasks.iterator();
}// 3. 清理任务数据
Iterator taskIterator = mAllPositionTasks.iterator();
while (taskIterator.hasNext()) {
PositionTaskModel task = taskIterator.next();
PositionTaskModel task = (PositionTaskModel)taskIterator.next();
if (task != null && removedPosId.equals(task.getPositionId())) {
taskIterator.remove();
}
}
mPositionTaskMap.remove(removedPosId);
mPositionList.remove(position);
LogUtils.d(TAG, "删除位置:清理任务数据(位置ID=" + removedPosId + "剩余列表数=" + mPositionList.size());
// 4. 同步服务
LogUtils.d(TAG, "删除位置:清理任务数据(剩余列表数=" + mPositionList.size() + "");// 4. 同步服务(传递更新后的列表)
if (isServiceBound && mDistanceService != null) {
mDistanceService.syncPositionList(mPositionList);
mDistanceService.syncPositionList(mPositionList); // 同步删除后的列表
mDistanceService.syncAllPositionTasks(mAllPositionTasks);
mDistanceService.removeVisibleDistanceView(removedPosId);
LogUtils.d(TAG, "删除位置:同步服务数据位置ID=" + removedPosId + "");
}
// 刷新视图
notifyItemRemoved(position);
LogUtils.d(TAG, "删除位置:同步服务位置ID=" + removedPosId + "");
}notifyItemRemoved(position);
notifyItemRangeChanged(position, mPositionList.size());
}
/**
* 更新所有位置Java7双迭代器清理无效数据
- 更新所有位置(传递原列表引用,清理无效映射)
*/
public void updateAllPositions(ArrayList<PositionModel> newPositionList) {
public void updateAllPositions(ArrayList newPositionList) {
if (newPositionList == null) {
LogUtils.e(TAG, "更新所有位置失败:新位置列表为空");
LogUtils.e(TAG, "更新所有位置失败:新列表为空");
return;
}
mPositionList.clear();
mPositionList.addAll(newPositionList);
LogUtils.d(TAG, "更新所有位置:接收新列表(数量=" + newPositionList.size() + "");
// 1. 清理本地无效可见控件Java7迭代器遍历+判断存在性)
Iterator<String> distanceViewIter = mVisibleDistanceViews.keySet().iterator();
LogUtils.d(TAG, "更新所有位置:接收新列表(数量=" + newPositionList.size() + "");// 1. 清理无效可见控件
Iterator distanceViewIter = mVisibleDistanceViews.keySet().iterator();
while (distanceViewIter.hasNext()) {
String posId = distanceViewIter.next();
boolean isPosExist = false;
Iterator<PositionModel> modelIter = newPositionList.iterator();
String posId = (String)distanceViewIter.next();
boolean isExist = false;
Iterator modelIter = newPositionList.iterator();
while (modelIter.hasNext()) {
PositionModel model = modelIter.next();
if (posId.equals(model.getPositionId())) {
isPosExist = true;
if (posId.equals(((PositionModel)modelIter.next()).getPositionId())) {
isExist = true;
break;
}
}
if (!isPosExist) {
if (!isExist) {
distanceViewIter.remove();
LogUtils.d(TAG, "更新所有位置:清理无效可见控件位置ID=" + posId + "");
LogUtils.d(TAG, "更新所有位置清理无效控件位置ID=" + posId + "");
}
}
// 2. 清理任务映射表无效项Java7迭代器遍历
Iterator<String> taskMapKeyIter = mPositionTaskMap.keySet().iterator();
while (taskMapKeyIter.hasNext()) {
String posId = taskMapKeyIter.next();
boolean isPosExist = false;
Iterator<PositionModel> modelIter = newPositionList.iterator();
}// 2. 清理无效任务映射
Iterator taskMapIter = mPositionTaskMap.keySet().iterator();
while (taskMapIter.hasNext()) {
String posId = (String)taskMapIter.next();
boolean isExist = false;
Iterator modelIter = newPositionList.iterator();
while (modelIter.hasNext()) {
PositionModel model = modelIter.next();
if (posId.equals(model.getPositionId())) {
isPosExist = true;
if (posId.equals(((PositionModel)modelIter.next()).getPositionId())) {
isExist = true;
break;
}
}
if (!isPosExist) {
taskMapKeyIter.remove();
if (!isExist) {
taskMapIter.remove();
LogUtils.d(TAG, "更新所有位置清理无效任务映射位置ID=" + posId + "");
}
}
// 3. 重新初始化索引映射Java7普通for循环避免迭代器索引问题
}// 3. 重新初始化索引映射
mPositionIdToIndexMap.clear();
for (int i = 0; i < newPositionList.size(); i++) {
PositionModel model = newPositionList.get(i);
PositionModel model = (PositionModel)newPositionList.get(i);
String posId = model.getPositionId();
mPositionIdToIndexMap.put(posId, i);
// 初始化新位置的任务列表(若不存在)
// 初始化新位置的任务列表
if (!mPositionTaskMap.containsKey(posId)) {
mPositionTaskMap.put(posId, new ArrayList<PositionTaskModel>());
LogUtils.d(TAG, "更新所有位置:初始化新位置任务列表位置ID=" + posId + "");
mPositionTaskMap.put(posId, new ArrayList());
LogUtils.d(TAG, "更新所有位置初始化新任务列表位置ID=" + posId + "");
}
}
// 4. 同步服务
}// 4. 同步服务(传递原列表引用)
if (isServiceBound && mDistanceService != null) {
mDistanceService.syncPositionList(mPositionList);
mDistanceService.syncPositionList(mPositionList); // 同步更新后的列表
mDistanceService.clearVisibleDistanceViews();
// 同步有效可见控件Java7迭代器遍历
Iterator<String> validPosIter = mVisibleDistanceViews.keySet().iterator();
// 同步有效可见控件
Iterator validPosIter = mVisibleDistanceViews.keySet().iterator();
while (validPosIter.hasNext()) {
mDistanceService.addVisibleDistanceView(validPosIter.next());
mDistanceService.addVisibleDistanceView((String)validPosIter.next());
}
LogUtils.d(TAG, "更新所有位置:同步服务数据(可见控件数=" + mVisibleDistanceViews.size() + "");
}
// 刷新视图
notifyDataSetChanged();
LogUtils.d(TAG, "更新所有位置:同步服务(可见控件数=" + mVisibleDistanceViews.size() + "");
}notifyDataSetChanged();
}
/**
* 批量切换简单视图Java7迭代器遍历
- 批量切换简单视图
*/
public void switchAllToSimpleView() {
Iterator<PositionModel> modelIterator = mPositionList.iterator();
Iterator modelIterator = mPositionList.iterator();
while (modelIterator.hasNext()) {
PositionModel model = modelIterator.next();
model.setIsSimpleView(true);
((PositionModel)modelIterator.next()).setIsSimpleView(true);
}
notifyDataSetChanged();
LogUtils.d(TAG, "批量切换简单视图:已切换所有位置(总数=" + mPositionList.size() + "");
}
/**
* 获取位置列表Java7返回新列表避免外部修改
- 获取位置列表(返回新列表,避免外部修改原引用)
*/
public ArrayList<PositionModel> getPositionList() {
return new ArrayList<PositionModel>(mPositionList);
public ArrayList getPositionList() {
return new ArrayList(mPositionList);
}
// ---------------------- ViewHolder 定义完全兼容Java7 ----------------------
@@ -860,7 +869,7 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
public SimpleViewHolder(@NonNull View itemView) {
super(itemView);
// Java7显式 findViewById + 类型转换
// 显式findViewById+类型转换Java7兼容
tvSimpleLongitude = (TextView) itemView.findViewById(R.id.tv_simple_longitude);
tvSimpleLatitude = (TextView) itemView.findViewById(R.id.tv_simple_latitude);
tvSimpleMemo = (TextView) itemView.findViewById(R.id.tv_simple_memo);
@@ -873,32 +882,74 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
TextView tvEditLongitude;
TextView tvEditLatitude;
EditText etEditMemo;
TextView tvEditRealDistance;
RadioGroup rgRealDistanceSwitch;
RadioButton rbDisable;
RadioButton rbEnable;
Button btnEditDelete;
Button btnEditCancel;
Button btnEditConfirm;
RadioButton rbDisable;
PositionTaskListView ptlvEditTasks;
Button btnAddTask;
TextView tvEditRealDistance;
Button btnEditConfirm;
Button btnEditCancel;
Button btnEditDelete;
public EditViewHolder(@NonNull View itemView) {
super(itemView);
// Java7显式 findViewById + 类型转换
// 显式findViewById+类型转换Java7兼容避免空指针
tvEditLongitude = (TextView) itemView.findViewById(R.id.tv_edit_longitude);
tvEditLatitude = (TextView) itemView.findViewById(R.id.tv_edit_latitude);
etEditMemo = (EditText) itemView.findViewById(R.id.et_edit_memo);
tvEditRealDistance = (TextView) itemView.findViewById(R.id.tv_edit_real_distance);
rgRealDistanceSwitch = (RadioGroup) itemView.findViewById(R.id.rg_real_distance_switch);
rbDisable = (RadioButton) itemView.findViewById(R.id.rb_disable);
rbEnable = (RadioButton) itemView.findViewById(R.id.rb_enable);
btnEditDelete = (Button) itemView.findViewById(R.id.btn_edit_delete);
btnEditCancel = (Button) itemView.findViewById(R.id.btn_edit_cancel);
btnEditConfirm = (Button) itemView.findViewById(R.id.btn_edit_confirm);
rbDisable = (RadioButton) itemView.findViewById(R.id.rb_disable);
ptlvEditTasks = (PositionTaskListView) itemView.findViewById(R.id.ptlv_edit_tasks);
btnAddTask = (Button) itemView.findViewById(R.id.btn_add_task);
tvEditRealDistance = (TextView) itemView.findViewById(R.id.tv_edit_real_distance);
}
btnEditConfirm = (Button) itemView.findViewById(R.id.btn_edit_confirm);
btnEditCancel = (Button) itemView.findViewById(R.id.btn_edit_cancel);
btnEditDelete = (Button) itemView.findViewById(R.id.btn_edit_delete);
}
}
/**
- 辅助方法获取指定位置ID的任务列表对外提供只读访问
*/
public ArrayList getTasksByPositionId(String positionId) {
ArrayList tasks = getSafeTasks(positionId);
return new ArrayList(tasks); // 返回拷贝,避免外部修改原数据
}
/**
- 辅助方法:清空所有数据(适配服务同步)
*/
public void clearAllData() {
mPositionList.clear();
mAllPositionTasks.clear();
mPositionTaskMap.clear();
mVisibleDistanceViews.clear();
mPositionIdToIndexMap.clear();// 同步服务清理
if (isServiceBound && mDistanceService != null) {
mDistanceService.syncPositionList(mPositionList);
mDistanceService.syncAllPositionTasks(mAllPositionTasks);
mDistanceService.clearVisibleDistanceViews();
LogUtils.d(TAG, "清空所有数据:同步服务完成");
}notifyDataSetChanged();
LogUtils.d(TAG, "清空所有数据:本地数据已重置");
}
/**
- 生命周期方法:解绑服务(避免内存泄漏,供外部调用)
*/
public void onDestroy() {
unbindDistanceRefreshService();
// 释放强引用
mContext = null;
mCurrentGpsPosition = null;
mOnDeleteClickListener = null;
mOnSavePositionClickListener = null;
mOnSavePositionTaskClickListener = null;
LogUtils.d(TAG, "Adapter生命周期结束已解绑服务并释放资源");
}
}

View File

@@ -22,7 +22,7 @@ public class PositionModel extends BaseBean {
double latitude;
// 位置备注(空值时显示“无备注”)
String memo;
// 定位点与指定点实时距离大小
// 定位点与指定点实时距离长度
double realPositionDistance;
// 是否启用实时距离计算
boolean isEnableRealPositionDistance;

View File

@@ -8,6 +8,7 @@ package cc.winboll.studio.positions.services;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -38,21 +39,20 @@ public class DistanceRefreshService extends Service {
public static final long REFRESH_INTERVAL = 5000; // 5秒刷新一次
public static final int MSG_UPDATE_DISTANCE = 1001;
public static final String KEY_POSITION_ID = "key_position_id";
public static final String KEY_DISTANCE_TEXT = "key_distance_text";
public static final String KEY_DISTANCE_COLOR = "key_distance_color";
// 核心成员变量Java7明确泛型初始化
private Timer mDistanceTimer;
private Handler mMainHandler;
private PositionModel mCurrentGpsPosition;
private ArrayList<PositionModel> mPositionList;
private ArrayList<PositionModel> mPositionList; // 持有Adapter传递的原列表引用
private ArrayList<PositionTaskModel> mAllPositionTasks;
private Map<String, Integer> mVisibleDistanceViewTags = new HashMap<String, Integer>();
private OnDistanceUpdateReceiver mUpdateReceiver;
private boolean isPositionListSynced = false; // 新增:标记位置列表是否已同步
// 数据同步与消息接收接口Activity/Adapter实现
public interface OnDistanceUpdateReceiver {
void onDistanceUpdate(String positionId, String distanceText, int distanceColor);
void onDistanceUpdate(String positionId); // 简化仅传递位置ID
int getColorRes(int resId);
}
@@ -75,13 +75,13 @@ public class DistanceRefreshService extends Service {
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == MSG_UPDATE_DISTANCE && mUpdateReceiver != null) {
// 解析消息Java7显式调用getData(),避免链式调用)
String positionId = msg.getData().getString(KEY_POSITION_ID);
String distanceText = msg.getData().getString(KEY_DISTANCE_TEXT);
int distanceColor = msg.getData().getInt(KEY_DISTANCE_COLOR);
LogUtils.d(TAG, "接收消息→转发更新位置ID=" + positionId + ",距离文本=" + distanceText);
mUpdateReceiver.onDistanceUpdate(positionId, distanceText, distanceColor);
// 解析消息仅获取位置ID
Bundle data = msg.getData();
String positionId = data.getString(KEY_POSITION_ID);
if (positionId != null) {
LogUtils.d(TAG, "接收消息→转发更新位置ID=" + positionId);
mUpdateReceiver.onDistanceUpdate(positionId);
}
}
}
};
@@ -117,7 +117,7 @@ public class DistanceRefreshService extends Service {
mDistanceTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
LogUtils.d(TAG, "定时器触发→开始计算距离,可见位置数量=" + mVisibleDistanceViewTags.size());
LogUtils.d(TAG, "定时器触发→开始计算距离,位置列表同步状态=" + isPositionListSynced);
calculateAndSendDistanceUpdates();
checkAndTriggerTasks();
}
@@ -125,75 +125,47 @@ public class DistanceRefreshService extends Service {
}
/**
* 计算距离并发送UI更新消息
* Java7使用迭代器遍历Map替代forEach Lambda,显式空判断
* 核心修改计算距离并更新到mPositionList仅发送位置ID通知
* Java7使用迭代器遍历显式空判断
*/
private void calculateAndSendDistanceUpdates() {
// 无可见控件/数据/接收器时,直接返回
if (mVisibleDistanceViewTags.isEmpty()) {
LogUtils.d(TAG, "无需要更新的可见控件,跳过计算");
// 前置校验:位置列表未同步/为空/无GPS,直接返回
if (!isPositionListSynced || mPositionList.isEmpty()) {
LogUtils.d(TAG, "位置列表未同步/为空,跳过距离计算");
return;
}
if (mPositionList.isEmpty()) {
LogUtils.d(TAG, "位置列表为空,无法计算距离");
return;
}
if (mUpdateReceiver == null) {
LogUtils.d(TAG, "未设置消息接收器Adapter未绑定无法发送更新");
if (mCurrentGpsPosition == null) {
LogUtils.d(TAG, "无当前GPS位置跳过距离计算");
return;
}
// Java7使用Iterator遍历Map.Entry替代forEach Lambda
Iterator<Map.Entry<String, Integer>> entryIterator = mVisibleDistanceViewTags.entrySet().iterator();
while (entryIterator.hasNext()) {
Map.Entry<String, Integer> entry = entryIterator.next();
String positionId = entry.getKey();
PositionModel targetModel = findPositionModelById(positionId);
// 遍历所有位置项计算并设置realPositionDistance
Iterator<PositionModel> positionIter = mPositionList.iterator();
while (positionIter.hasNext()) {
PositionModel targetModel = positionIter.next();
String positionId = targetModel.getPositionId();
if (targetModel == null) {
// 位置模型不存在时,发送“无效位置”消息
sendDistanceUpdateMessage(
positionId,
"实时距离:位置无效",
mUpdateReceiver.getColorRes(R.color.colorRed)
);
LogUtils.d(TAG, "位置ID=" + positionId + " 未找到对应模型,发送无效提示");
continue;
}
// 距离计算与文本生成
String distanceText;
int distanceColor;
if (!targetModel.isEnableRealPositionDistance()) {
distanceText = "实时距离:未启用";
distanceColor = mUpdateReceiver.getColorRes(R.color.colorGrayText);
} else if (mCurrentGpsPosition == null) {
// 无GPS时持续发送“等待定位”避免默认文本回落
distanceText = "实时距离等待GPS定位";
distanceColor = mUpdateReceiver.getColorRes(R.color.colorGrayText);
LogUtils.d(TAG, "位置ID=" + positionId + " 无GPS数据发送等待提示");
} else {
if (targetModel.isEnableRealPositionDistance()) {
// 状态为true计算距离设置到realPositionDistance
try {
// 计算距离复用PositionModel静态方法
double distanceM = PositionModel.calculatePositionDistance(mCurrentGpsPosition, targetModel, false);
judgeTaskBingoStatus(targetModel, (int) distanceM);
// 格式化距离文本Java7显式类型转换避免自动拆箱问题
if (distanceM < 1000) {
distanceText = String.format("实时距离:%.1f 米", distanceM);
} else {
distanceText = String.format("实时距离:%.1f 千米", distanceM / 1000);
}
distanceColor = mUpdateReceiver.getColorRes(R.color.colorEnableGreen);
LogUtils.d(TAG, "位置ID=" + positionId + " 计算完成:" + distanceText);
double distanceM = PositionModel.calculatePositionDistance(
mCurrentGpsPosition, targetModel, false
);
targetModel.setRealPositionDistance(distanceM); // 存储计算结果到列表项
LogUtils.d(TAG, "位置ID=" + positionId + " 计算距离:" + distanceM + "");
} catch (IllegalArgumentException e) {
distanceText = "实时距离:数据无效";
distanceColor = mUpdateReceiver.getColorRes(R.color.colorRed);
LogUtils.e(TAG, "位置ID=" + positionId + " 计算异常:" + e.getMessage());
// 计算异常时,设置为-1标记无效
targetModel.setRealPositionDistance(-1);
LogUtils.e(TAG, "位置ID=" + positionId + " 距离计算异常:" + e.getMessage());
}
} else {
// 状态为false强制设置realPositionDistance为-1
targetModel.setRealPositionDistance(-1);
LogUtils.d(TAG, "位置ID=" + positionId + " 未启用距离计算,设置距离为-1");
}
// 发送消息到UI线程
sendDistanceUpdateMessage(positionId, distanceText, distanceColor);
// 发送更新通知仅传位置ID
sendDistanceUpdateMessage(positionId);
}
}
@@ -202,7 +174,7 @@ public class DistanceRefreshService extends Service {
* Java7使用迭代器遍历任务列表替代forEach Lambda
*/
private void checkAndTriggerTasks() {
if (mAllPositionTasks.isEmpty()) {
if (mAllPositionTasks.isEmpty() || !isPositionListSynced || mPositionList.isEmpty()) {
return;
}
// Java7Iterator遍历ArrayList替代forEach Lambda
@@ -216,65 +188,70 @@ public class DistanceRefreshService extends Service {
}
/**
* 判断任务触发状态(仅修改数据UI更新由Adapter处理
* 新增:判断任务触发状态(基于mPositionList中的realPositionDistance
* Java7迭代器遍历任务列表显式状态判断
*/
private void judgeTaskBingoStatus(PositionModel model, int distanceM) {
String targetPosId = model.getPositionId();
// Java7Iterator遍历任务列表
Iterator<PositionTaskModel> taskIterator = mAllPositionTasks.iterator();
while (taskIterator.hasNext()) {
PositionTaskModel task = taskIterator.next();
if (targetPosId.equals(task.getPositionId())) {
private void judgeTaskBingoStatus() {
if (!isPositionListSynced || mPositionList.isEmpty() || mAllPositionTasks.isEmpty()) {
return;
}
Iterator<PositionModel> posIter = mPositionList.iterator();
while (posIter.hasNext()) {
PositionModel posModel = posIter.next();
String posId = posModel.getPositionId();
double distanceM = posModel.getRealPositionDistance();
// 遍历绑定当前位置的任务
Iterator<PositionTaskModel> taskIter = mAllPositionTasks.iterator();
while (taskIter.hasNext()) {
PositionTaskModel task = taskIter.next();
if (posId.equals(task.getPositionId()) && distanceM != -1) {
boolean oldBingoState = task.isBingo();
boolean newBingoState = false;
// 根据任务条件判断新状态Java7if-else替代三元表达式增强可读性
// 根据任务条件判断新状态
if (task.isGreaterThan()) {
newBingoState = task.isEnable() && distanceM > task.getDiscussDistance();
} else if (task.isLessThan()) {
newBingoState = task.isEnable() && distanceM < task.getDiscussDistance();
} else {
newBingoState = task.isEnable();
}
// 更新任务状态(仅状态变化时更新
// 仅状态变化时更新
if (newBingoState != oldBingoState) {
task.setIsBingo(newBingoState);
}
}
}
}
}
/**
* 发送距离更新消息通过Handler发送到UI线程
* 简化仅发送位置ID通知Adapter从mPositionList读取数据
* Java7显式创建Message避免obtainMessage链式调用
*/
private void sendDistanceUpdateMessage(String positionId, String distanceText, int distanceColor) {
private void sendDistanceUpdateMessage(String positionId) {
Message msg = mMainHandler.obtainMessage(MSG_UPDATE_DISTANCE);
// Java7显式调用put方法替代链式put
msg.getData().putString(KEY_POSITION_ID, positionId);
msg.getData().putString(KEY_DISTANCE_TEXT, distanceText);
msg.getData().putInt(KEY_DISTANCE_COLOR, distanceColor);
Bundle data = new Bundle();
data.putString(KEY_POSITION_ID, positionId);
msg.setData(data);
mMainHandler.sendMessage(msg);
LogUtils.d(TAG, "发送消息→位置ID=" + positionId + ",距离文本=" + distanceText);
LogUtils.d(TAG, "发送更新通知:位置ID=" + positionId);
}
/**
* 根据位置ID查找位置模型工具方法
* Java7迭代器遍历位置列表替代stream().filter()
* 核心修改:同步位置列表(持有原引用,不拷贝
*/
private PositionModel findPositionModelById(String positionId) {
// Java7Iterator遍历ArrayList
Iterator<PositionModel> modelIterator = mPositionList.iterator();
while (modelIterator.hasNext()) {
PositionModel model = modelIterator.next();
if (positionId.equals(model.getPositionId())) {
return model;
public void syncPositionList(ArrayList<PositionModel> positionList) {
if (positionList != null) {
this.mPositionList = positionList; // 持有外部列表引用
this.isPositionListSynced = true;
LogUtils.d(TAG, "同步位置列表(持有引用):数量=" + positionList.size());
} else {
this.isPositionListSynced = false;
LogUtils.w(TAG, "同步位置列表失败传入列表为null");
}
}
return null;
}
// ---------------------- 对外API供Activity/Adapter调用 ----------------------
public void setOnDistanceUpdateReceiver(OnDistanceUpdateReceiver receiver) {
@@ -286,14 +263,6 @@ public class DistanceRefreshService extends Service {
LogUtils.d(TAG, "同步GPS位置纬度=" + (currentGpsPosition != null ? currentGpsPosition.getLatitude() : 0.0f));
}
public void syncPositionList(ArrayList<PositionModel> positionList) {
if (positionList != null) {
this.mPositionList.clear();
this.mPositionList.addAll(positionList);
LogUtils.d(TAG, "同步位置列表:数量=" + positionList.size());
}
}
public void syncAllPositionTasks(ArrayList<PositionTaskModel> allPositionTasks) {
if (allPositionTasks != null) {
this.mAllPositionTasks.clear();
@@ -331,10 +300,11 @@ public class DistanceRefreshService extends Service {
}
// 清空数据,解除引用(避免内存泄漏)
mCurrentGpsPosition = null;
mPositionList.clear();
mPositionList = null; // 释放列表引用
mAllPositionTasks.clear();
mVisibleDistanceViewTags.clear();
mUpdateReceiver = null;
isPositionListSynced = false;
}
}