diff --git a/app/build.gradle b/app/build.gradle index 47ab5f5..37cef09 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -255,6 +255,8 @@ dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel:2.10.0" implementation "androidx.lifecycle:lifecycle-livedata:2.10.0" implementation "androidx.lifecycle:lifecycle-runtime:2.10.0" + // 可选:RxJava3 Observable → LiveData 的桥接 + implementation 'androidx.lifecycle:lifecycle-reactivestreams:2.10.0' kapt "androidx.lifecycle:lifecycle-compiler:2.10.0" // LifecycleService 核心库 implementation "androidx.lifecycle:lifecycle-service:2.10.0" diff --git a/app/src/main/java/com/ttstd/dialer/service/main/MainService.java b/app/src/main/java/com/ttstd/dialer/service/main/MainService.java index 9ead7cf..5e94a59 100644 --- a/app/src/main/java/com/ttstd/dialer/service/main/MainService.java +++ b/app/src/main/java/com/ttstd/dialer/service/main/MainService.java @@ -13,8 +13,15 @@ import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.LifecycleRegistry; import androidx.lifecycle.Observer; +import androidx.lifecycle.ViewModelProvider; +import androidx.lifecycle.ViewModelStore; +import androidx.lifecycle.ViewModelStoreOwner; import com.blankj.utilcode.util.NetworkUtils; import com.kongzue.dialogx.dialogs.PopTip; @@ -33,7 +40,7 @@ import com.ttstd.dialer.manager.MqttManager; import com.ttstd.dialer.utils.Logger; import com.ttstd.dialer.utils.SystemUtils; -public class MainService extends BaseService implements NetworkUtils.OnNetworkStatusChangedListener { +public class MainService extends BaseService implements NetworkUtils.OnNetworkStatusChangedListener, ViewModelStoreOwner { private static final String TAG = "MainService"; public static final String SHOW_FLOAT_WINDOW_ACTION = "show_float_window"; @@ -49,6 +56,28 @@ public class MainService extends BaseService implements NetworkUtils.OnNetworkSt private WindowManager.LayoutParams mLayoutParams; private boolean mFloatWindowShowing = false; + /** + * ViewModelStore:Service 销毁时自动清空,从而触发 ViewModel.onCleared(), + * 保证 ViewModel 内部 RxJava 任务被正确取消,避免内存泄漏。 + */ + private final ViewModelStore mViewModelStore = new ViewModelStore(); + + // ============================================================ + // ViewModelStoreOwner 实现 + // ============================================================ + + @NonNull + @Override + public ViewModelStore getViewModelStore() { + return mViewModelStore; + } + + @NonNull + @Override + public Lifecycle getLifecycle() { + return super.getLifecycle(); + } + @Override public void onDisconnected() { Logger.e(TAG, "onDisconnected: "); @@ -76,8 +105,9 @@ public class MainService extends BaseService implements NetworkUtils.OnNetworkSt NetworkUtils.registerNetworkStatusChangedListener(this); - // 初始化ViewModel(绑定上下文+View回调) - mViewModel = new MainServiceModel(); + // 通过 ViewModelProvider 创建 ViewModel(由 ViewModelStore 统一管理生命周期, + // 在 Service 销毁时自动触发 ViewModel.onCleared() 取消进行中的 RxJava 任务) + mViewModel = new ViewModelProvider(this).get(MainServiceModel.class); // 注入 Repository(数据访问统一走 Data 层,避免 ViewModel 直接触网) mViewModel.setSnRepository(SnRepository.getInstance(this)); @@ -247,6 +277,8 @@ public class MainService extends BaseService implements NetworkUtils.OnNetworkSt if (floatingView != null) { mWindowManager.removeView(floatingView); } + // 清空 ViewModelStore,触发 ViewModel.onCleared(),取消进行中的 RxJava 任务,避免内存泄漏 + mViewModelStore.clear(); } @Override