diff --git a/positions/src/main/java/cc/winboll/studio/positions/activities/LocationActivity.java b/positions/src/main/java/cc/winboll/studio/positions/activities/LocationActivity.java index 296b21b..cee8fe8 100644 --- a/positions/src/main/java/cc/winboll/studio/positions/activities/LocationActivity.java +++ b/positions/src/main/java/cc/winboll/studio/positions/activities/LocationActivity.java @@ -1,11 +1,5 @@ package cc.winboll.studio.positions.activities; -/** - * @Author 豆包&ZhanGSKen - * @CreateTime 2025/09/29 18:22:00 - * @EditTime 2026/05/03 15:32:10 - * @Describe 位置列表页面,适配MainService GPS接口、规范服务交互、完善生命周期资源释放 - */ import android.app.Activity; import android.content.ComponentName; import android.content.Context; @@ -26,6 +20,7 @@ import cc.winboll.studio.libaes.dialogs.YesNoAlertDialog; import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity; import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.ToastUtils; +import cc.winboll.studio.positions.App; import cc.winboll.studio.positions.MainActivity; import cc.winboll.studio.positions.R; import cc.winboll.studio.positions.adapters.PositionAdapter; @@ -38,10 +33,17 @@ import java.util.Date; import java.util.Locale; import java.util.concurrent.atomic.AtomicBoolean; +/** + * @Author 豆包&ZhanGSKen + * @CreateTime 2025/09/29 18:22:00 + * @EditTime 2026/05/03 16:36:54 + * @Describe 位置列表页面,适配MainService GPS接口、规范服务交互、完善生命周期资源释放,新增应用空转状态副标题提示 + */ public class LocationActivity extends WinBoLLActivity implements IWinBoLLActivity { + // 常量 public static final String TAG = "LocationActivity"; - // ======================== 全局属性 ======================== + // 成员属性有序排版 private Toolbar mToolbar; private RecyclerView mRvPosition; private PositionAdapter mPositionAdapter; @@ -54,11 +56,11 @@ public class LocationActivity extends WinBoLLActivity implements IWinBoLLActivit private PositionModel mCurrentGpsPos; private final ArrayList mLocalPosCache = new ArrayList(); - // ======================== 服务连接回调 ======================== + // 服务连接回调 private final ServiceConnection mServiceConnection = new ServiceConnection() { @Override - public void onServiceConnected(ComponentName name, IBinder service) { - LogUtils.d(TAG,"onServiceConnected 执行"); + public void onServiceConnected(final ComponentName name, final IBinder service) { + LogUtils.d(TAG, "onServiceConnected invoke"); if (!(service instanceof MainService.LocalBinder)) { LogUtils.e(TAG, "服务绑定失败:Binder类型不匹配"); isServiceBound.set(false); @@ -66,16 +68,16 @@ public class LocationActivity extends WinBoLLActivity implements IWinBoLLActivit } try { - MainService.LocalBinder binder = (MainService.LocalBinder) service; + final MainService.LocalBinder binder = (MainService.LocalBinder) service; mMainService = binder.getService(); isServiceBound.set(true); - LogUtils.d(TAG,"MainService 绑定成功"); + LogUtils.d(TAG, "MainService bind success"); syncDataFromMainService(); registerGpsListener(); initPositionAdapter(); - } catch (Exception e) { - LogUtils.e(TAG,"服务绑定初始化异常:" + e.getMessage()); + } catch (final Exception e) { + LogUtils.e(TAG, "服务绑定异常:" + e.getMessage()); isServiceBound.set(false); mMainService = null; showToast("服务初始化失败,无法加载数据"); @@ -83,15 +85,15 @@ public class LocationActivity extends WinBoLLActivity implements IWinBoLLActivit } @Override - public void onServiceDisconnected(ComponentName name) { - LogUtils.w(TAG,"MainService 断开连接"); + public void onServiceDisconnected(final ComponentName name) { + LogUtils.w(TAG, "MainService 服务断开"); mMainService = null; isServiceBound.set(false); isAdapterInited.set(false); } }; - // ======================== 接口实现 ======================== + // 接口方法实现 @Override public Activity getActivity() { return this; @@ -102,137 +104,84 @@ public class LocationActivity extends WinBoLLActivity implements IWinBoLLActivit return TAG; } - // ======================== 生命周期 ======================== - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - LogUtils.d(TAG,"onCreate 进入"); - setContentView(R.layout.activity_location); - - mToolbar = findViewById(R.id.toolbar); - setSupportActionBar(mToolbar); - mToolbar.setSubtitle(getTag()); - mToolbar.setTitleTextAppearance(this, R.style.Toolbar_TitleText); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - mToolbar.setNavigationOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - LogUtils.d(TAG,"点击导航返回按钮"); - startActivity(new Intent(LocationActivity.this, MainActivity.class)); - finish(); - } - }); - - initView(); - initGpsUpdateListener(); - bindMainService(); - } - - @Override - protected void onResume() { - super.onResume(); - LogUtils.d(TAG,"onResume 进入"); - if (isServiceBound.get() && mMainService != null && !isAdapterInited.get()) { - syncDataFromMainService(); - initPositionAdapter(); - } else if (isServiceBound.get() && mMainService != null - && isAdapterInited.get() && mPositionAdapter != null) { - syncDataFromMainService(); - mPositionAdapter.notifyDataSetChanged(); + /** + * 刷新空转状态副标题 + */ + private void refreshIdleStatusTitle() { + LogUtils.d(TAG, "refreshIdleStatusTitle invoke"); + if (mToolbar == null) { + LogUtils.w(TAG, "Toolbar为空,跳过刷新"); + return; + } + final boolean idleStatus = App.isAppIdleRunning(); + if (idleStatus) { + mToolbar.setSubtitle("当前状态:应用正在空转运行"); + LogUtils.d(TAG, "检测应用空转状态为 : " + idleStatus); + } else { + mToolbar.setSubtitle(getTag()); } } - @Override - protected void onPause() { - super.onPause(); - LogUtils.d(TAG,"onPause 页面进入后台"); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - LogUtils.d(TAG,"onDestroy 开始释放资源"); - - unregisterGpsListener(); - - if (mPositionAdapter != null) { - mPositionAdapter.release(); - mPositionAdapter = null; - LogUtils.d(TAG,"Adapter资源已释放"); - } - - if (isServiceBound.get()) { - try { - unbindService(mServiceConnection); - LogUtils.d(TAG,"MainService 解绑完成"); - } catch (IllegalArgumentException e) { - LogUtils.e(TAG,"解绑异常:服务已提前解绑"); - } - isServiceBound.set(false); - mMainService = null; - } - - synchronized (mLocalPosCache) { - mLocalPosCache.clear(); - } - mCurrentGpsPos = null; - mGpsUpdateListener = null; - isAdapterInited.set(false); - LogUtils.d(TAG,"全部资源释放完毕"); - } - - // ======================== 视图初始化 ======================== + /** + * 初始化页面控件 + */ private void initView() { - LogUtils.d(TAG,"initView 执行视图初始化"); + LogUtils.d(TAG, "initView invoke"); mRvPosition = findViewById(R.id.rv_position_list); - LinearLayoutManager layoutManager = new LinearLayoutManager(this); + final LinearLayoutManager layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); mRvPosition.setLayoutManager(layoutManager); mLocalPosCache.clear(); } - // ======================== 服务绑定 ======================== + /** + * 绑定后台服务 + */ private void bindMainService() { - LogUtils.d(TAG,"bindMainService 发起服务绑定"); + LogUtils.d(TAG, "bindMainService invoke"); if (isServiceBound.get()) { - LogUtils.w(TAG,"服务已绑定,无需重复操作"); + LogUtils.w(TAG, "服务已绑定,无需重复执行"); return; } - Intent serviceIntent = new Intent(this, MainService.class); - boolean bindSuccess = bindService(serviceIntent, mServiceConnection, BIND_AUTO_CREATE); + final Intent serviceIntent = new Intent(this, MainService.class); + final boolean bindSuccess = bindService(serviceIntent, mServiceConnection, BIND_AUTO_CREATE); if (!bindSuccess) { - LogUtils.e(TAG,"发起服务绑定请求失败"); + LogUtils.e(TAG, "发起服务绑定请求失败"); showToast("服务绑定失败,无法加载位置数据"); } } - // ======================== 数据同步 ======================== + /** + * 同步服务数据至本地缓存 + */ private void syncDataFromMainService() { - LogUtils.d(TAG,"syncDataFromMainService 开始同步服务数据"); + LogUtils.d(TAG, "syncDataFromMainService invoke"); if (!isServiceBound.get() || mMainService == null) { - LogUtils.w(TAG,"服务未就绪,使用本地缓存兜底"); + LogUtils.w(TAG, "服务未就绪,使用本地缓存"); return; } try { - ArrayList servicePosList = mMainService.getPositionList(); + final ArrayList servicePosList = mMainService.getPositionList(); synchronized (mLocalPosCache) { mLocalPosCache.clear(); if (servicePosList != null && !servicePosList.isEmpty()) { mLocalPosCache.addAll(servicePosList); } } - LogUtils.d(TAG,"数据同步完成,本地缓存数量:" + mLocalPosCache.size()); - } catch (Exception e) { - LogUtils.e(TAG,"同步服务数据异常:" + e.getMessage()); + LogUtils.d(TAG, "同步完成,缓存数量 : " + mLocalPosCache.size()); + } catch (final Exception e) { + LogUtils.e(TAG, "数据同步异常 : " + e.getMessage()); } } - // ======================== Adapter初始化 ======================== + /** + * 初始化列表适配器 + */ private void initPositionAdapter() { - LogUtils.d(TAG,"initPositionAdapter 开始初始化Adapter"); + LogUtils.d(TAG, "initPositionAdapter invoke"); if (isAdapterInited.get() || !isServiceBound.get() || mMainService == null || mRvPosition == null) { - LogUtils.w(TAG,"Adapter条件不满足,跳过初始化"); + LogUtils.w(TAG, "适配器初始化条件不满足,跳过"); return; } @@ -241,20 +190,21 @@ public class LocationActivity extends WinBoLLActivity implements IWinBoLLActivit mPositionAdapter.setOnDeleteClickListener(new PositionAdapter.OnDeleteClickListener() { @Override public void onDeleteClick(final int position) { + LogUtils.d(TAG, "onDeleteClick position = " + position); YesNoAlertDialog.show(LocationActivity.this, "删除位置提示", "是否删除此项锚点位置?", new YesNoAlertDialog.OnDialogResultListener() { @Override - public void onNo() {} + public void onNo() { + + } @Override public void onYes() { - LogUtils.d(TAG,"执行删除操作,索引:" + position); - if (position < 0 || position >= mLocalPosCache.size() - || !isServiceBound.get() || mMainService == null) { - LogUtils.w(TAG,"删除参数非法,操作终止"); + if (position < 0 || position >= mLocalPosCache.size()) { + LogUtils.w(TAG, "删除索引参数非法"); return; } - PositionModel deletePos = mLocalPosCache.get(position); + final PositionModel deletePos = mLocalPosCache.get(position); if (deletePos != null && !deletePos.getPositionId().isEmpty()) { mMainService.removePosition(deletePos.getPositionId()); synchronized (mLocalPosCache) { @@ -270,11 +220,10 @@ public class LocationActivity extends WinBoLLActivity implements IWinBoLLActivit mPositionAdapter.setOnSavePositionClickListener(new PositionAdapter.OnSavePositionClickListener() { @Override - public void onSavePositionClick(int position, PositionModel updatedPos) { - LogUtils.d(TAG,"执行保存修改,索引:" + position); - if (!isServiceBound.get() || mMainService == null - || position < 0 || position >= mLocalPosCache.size() || updatedPos == null) { - LogUtils.w(TAG,"保存参数非法,操作终止"); + public void onSavePositionClick(final int position, final PositionModel updatedPos) { + LogUtils.d(TAG, "onSavePositionClick position = " + position); + if (position < 0 || position >= mLocalPosCache.size() || updatedPos == null) { + LogUtils.w(TAG, "保存参数非法"); showToast("服务未就绪,保存失败"); return; } @@ -289,39 +238,43 @@ public class LocationActivity extends WinBoLLActivity implements IWinBoLLActivit mRvPosition.setAdapter(mPositionAdapter); isAdapterInited.set(true); - LogUtils.d(TAG,"PositionAdapter 初始化完成"); - } catch (Exception e) { - LogUtils.e(TAG,"Adapter初始化失败:" + e.getMessage()); + LogUtils.d(TAG, "适配器初始化完成"); + } catch (final Exception e) { + LogUtils.e(TAG, "适配器初始化异常 : " + e.getMessage()); isAdapterInited.set(false); mPositionAdapter = null; showToast("位置列表初始化失败,请重试"); } } - // ======================== 工具Toast ======================== - private void showToast(String content) { + /** + * 通用Toast弹窗 + */ + private void showToast(final String content) { if (isFinishing() || isDestroyed()) { - LogUtils.w(TAG,"Activity已销毁,取消Toast弹窗"); + LogUtils.w(TAG, "页面已销毁,取消Toast"); return; } Toast.makeText(this, content, Toast.LENGTH_SHORT).show(); } - // ======================== 新增位置 ======================== - public void addNewPosition(View view) { - LogUtils.d(TAG,"addNewPosition 触发新增位置"); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + /** + * 新增位置按钮事件 + */ + public void addNewPosition(final View view) { + LogUtils.d(TAG, "addNewPosition invoke"); + final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); if (imm != null && getCurrentFocus() != null) { imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); } if (!isServiceBound.get() || mMainService == null) { - LogUtils.w(TAG,"服务未绑定,无法新增位置"); + LogUtils.w(TAG, "服务未绑定,无法新增"); showToast("服务未就绪,无法新增位置"); return; } - PositionModel newPos = new PositionModel(); + final PositionModel newPos = new PositionModel(); newPos.setPositionId(PositionModel.genPositionId()); if (mCurrentGpsPos != null) { newPos.setLongitude(mCurrentGpsPos.getLongitude()); @@ -339,7 +292,7 @@ public class LocationActivity extends WinBoLLActivity implements IWinBoLLActivit synchronized (mLocalPosCache) { mLocalPosCache.add(newPos); } - LogUtils.d(TAG,"新增位置成功,ID:" + newPos.getPositionId()); + LogUtils.d(TAG, "新增位置成功,ID : " + newPos.getPositionId()); if (isAdapterInited.get() && mPositionAdapter != null) { mPositionAdapter.notifyItemInserted(mLocalPosCache.size() - 1); @@ -347,36 +300,39 @@ public class LocationActivity extends WinBoLLActivity implements IWinBoLLActivit showToast("新增位置成功(已启用GPS距离计算)"); } - // ======================== GPS监听管理 ======================== + /** + * 初始化GPS监听实例 + */ private void initGpsUpdateListener() { - LogUtils.d(TAG,"initGpsUpdateListener 初始化GPS监听"); + LogUtils.d(TAG, "initGpsUpdateListener invoke"); mGpsUpdateListener = new MainService.GpsUpdateListener() { @Override - public void onGpsPositionUpdated(PositionModel currentGpsPos) { + public void onGpsPositionUpdated(final PositionModel currentGpsPos) { if (currentGpsPos == null || isFinishing() || isDestroyed()) { return; } mCurrentGpsPos = currentGpsPos; - LogUtils.d(TAG,"GPS更新 纬度:" + currentGpsPos.getLatitude() - + " 经度:" + currentGpsPos.getLongitude()); + LogUtils.d(TAG, "GPS更新 -> 纬度:" + currentGpsPos.getLatitude() + " 经度:" + currentGpsPos.getLongitude()); - ((TextView)findViewById(R.id.tv_latitude)) - .setText(String.format("当前纬度:%f", currentGpsPos.getLatitude())); - ((TextView)findViewById(R.id.tv_longitude)) - .setText(String.format("当前经度:%f", currentGpsPos.getLongitude())); + final TextView tvLat = (TextView) findViewById(R.id.tv_latitude); + final TextView tvLon = (TextView) findViewById(R.id.tv_longitude); + final TextView tvTime = (TextView) findViewById(R.id.tv_timenow); - long currentTime = System.currentTimeMillis(); - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault()); - String timeStr = sdf.format(new Date(currentTime)); - ((TextView)findViewById(R.id.tv_timenow)).setText("现在时间:" + timeStr); + tvLat.setText(String.format("当前纬度:%f", currentGpsPos.getLatitude())); + tvLon.setText(String.format("当前经度:%f", currentGpsPos.getLongitude())); + + final long currentTime = System.currentTimeMillis(); + final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault()); + final String timeStr = sdf.format(new Date(currentTime)); + tvTime.setText("现在时间:" + timeStr); } @Override - public void onGpsStatusChanged(String status) { - if (status == null || isFinishing() || isDestroyed()){ + public void onGpsStatusChanged(final String status) { + if (status == null || isFinishing() || isDestroyed()) { return; } - LogUtils.d(TAG,"GPS状态变更:" + status); + LogUtils.d(TAG, "GPS状态变更 : " + status); if (status.contains("未开启") || status.contains("权限") || status.contains("失败")) { ToastUtils.show("GPS提示:" + status); } @@ -384,29 +340,117 @@ public class LocationActivity extends WinBoLLActivity implements IWinBoLLActivit }; } + /** + * 注册GPS监听 + */ private void registerGpsListener() { - LogUtils.d(TAG,"registerGpsListener 注册GPS监听"); - if (isFinishing() || isDestroyed() || !isServiceBound.get() - || mMainService == null || mGpsUpdateListener == null) { + LogUtils.d(TAG, "registerGpsListener invoke"); + if (isFinishing() || isDestroyed() || mMainService == null || mGpsUpdateListener == null) { return; } try { mMainService.registerGpsUpdateListener(mGpsUpdateListener); - } catch (Exception e) { - LogUtils.e(TAG,"GPS监听注册失败:" + e.getMessage()); + LogUtils.d(TAG, "GPS监听注册成功"); + } catch (final Exception e) { + LogUtils.e(TAG, "GPS注册异常 : " + e.getMessage()); } } + /** + * 反注册GPS监听 + */ private void unregisterGpsListener() { - LogUtils.d(TAG,"unregisterGpsListener 反注册GPS监听"); + LogUtils.d(TAG, "unregisterGpsListener invoke"); if (mMainService == null || mGpsUpdateListener == null) { return; } try { mMainService.unregisterGpsUpdateListener(mGpsUpdateListener); - } catch (Exception e) { - LogUtils.e(TAG,"GPS监听反注册失败:" + e.getMessage()); + LogUtils.d(TAG, "GPS监听反注册成功"); + } catch (final Exception e) { + LogUtils.e(TAG, "GPS反注册异常 : " + e.getMessage()); } } + + // 生命周期方法 + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + LogUtils.d(TAG, "onCreate invoke"); + setContentView(R.layout.activity_location); + + mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + mToolbar.setTitleTextAppearance(this, R.style.Toolbar_TitleText); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + mToolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(final View v) { + LogUtils.d(TAG, "点击返回导航按钮"); + final Intent intent = new Intent(LocationActivity.this, MainActivity.class); + startActivity(intent); + finish(); + } + }); + + refreshIdleStatusTitle(); + initView(); + initGpsUpdateListener(); + bindMainService(); + } + + @Override + protected void onResume() { + super.onResume(); + LogUtils.d(TAG, "onResume invoke"); + refreshIdleStatusTitle(); + + if (isServiceBound.get() && mMainService != null && !isAdapterInited.get()) { + syncDataFromMainService(); + initPositionAdapter(); + } else if (isServiceBound.get() && mMainService != null && mPositionAdapter != null) { + syncDataFromMainService(); + mPositionAdapter.notifyDataSetChanged(); + } + } + + @Override + protected void onPause() { + super.onPause(); + LogUtils.d(TAG, "onPause invoke"); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + LogUtils.d(TAG, "onDestroy invoke,开始释放资源"); + + unregisterGpsListener(); + + if (mPositionAdapter != null) { + mPositionAdapter.release(); + mPositionAdapter = null; + LogUtils.d(TAG, "Adapter资源释放完成"); + } + + if (isServiceBound.get()) { + try { + unbindService(mServiceConnection); + LogUtils.d(TAG, "服务解绑完成"); + } catch (final IllegalArgumentException e) { + LogUtils.e(TAG, "解绑异常:服务已提前解绑"); + } + isServiceBound.set(false); + mMainService = null; + } + + synchronized (mLocalPosCache) { + mLocalPosCache.clear(); + } + mCurrentGpsPos = null; + mGpsUpdateListener = null; + isAdapterInited.set(false); + LogUtils.d(TAG, "全部资源释放完毕"); + } }