feat(base): 添加MVVM、Rx生命周期和WebRTC控制端基础架构

引入BaseApplication、BaseService及MVVM基类(BaseViewModel/BaseMvvmActivity),
集成RxLifecycle管理生命周期,新增WebRTC控制端MainActivity与信令客户端,
建立屏幕捕获、推送、JPush等模块初始化流程,完善项目核心框架。
This commit is contained in:
TongTongStudio
2026-08-03 00:25:25 +08:00
parent 6eb2c7321a
commit 61398ff4ff
21 changed files with 1445 additions and 16 deletions

View File

@@ -0,0 +1,235 @@
package com.ttstd.dialer.base;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import androidx.multidex.MultiDex;
import com.alibaba.android.arouter.launcher.ARouter;
import com.arialyy.aria.core.Aria;
import com.kongzue.dialogx.DialogX;
import com.tencent.bugly.crashreport.CrashReport;
import com.tencent.mmkv.MMKV;
import com.ttstd.dialer.BuildConfig;
import com.ttstd.dialer.alarmclock.AlarmManagerHelper;
import com.ttstd.dialer.config.CommonConfig;
import com.ttstd.dialer.config.SystemIntentAction;
import com.ttstd.dialer.data.cache.CacheManager;
import com.ttstd.dialer.manager.AppManager;
import com.ttstd.dialer.manager.MapManager;
import com.ttstd.dialer.manager.WeatherManager;
import com.ttstd.dialer.mdm.DeviceManagerService;
import com.ttstd.dialer.network.OkHttpManager;
import com.ttstd.dialer.push.PushExecutor;
import com.ttstd.dialer.receiver.AppChangedReceiver;
import com.ttstd.dialer.receiver.HourlyChimeManager;
import com.ttstd.dialer.tts.sherpa_onnx.SherpaOnnxTtsManager;
import com.ttstd.dialer.utils.Logger;
import com.ttstd.dialer.utils.NativeUtils;
import com.ttstd.dialer.utils.SystemUtils;
import com.ttstd.iconloader.IconCacheManager;
import cn.jiguang.api.JCoreInterface;
import cn.jiguang.api.utils.JCollectionAuth;
import cn.jpush.android.api.JPushInterface;
public class BaseApplication extends Application {
private static final String TAG = "BaseApplication";
private MMKV mMMKV;
/**
* ViewModel中因为经常旋转导致弱引用为空
*/
@SuppressLint("StaticFieldLeak")
private static Context mAppContext;
public static Context getContext() {
return mAppContext;
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
@Override
public void onCreate() {
super.onCreate();
Logger.e(TAG, "onCreate: ");
mAppContext = getApplicationContext();
if (!BuildConfig.DEBUG) {
catchException();
}
// 在开始分析的地方调用,传入路径
// 如果是放到外部路径,需要添加权限
// 默认存储在/sdcard/Android/data/packagename/files
// Debug.startMethodTracing("App" + System.currentTimeMillis());
init();
}
@Override
public void onTerminate() {
super.onTerminate();
unregisterReceivers();
}
@Override
public void onLowMemory() {
super.onLowMemory();
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
}
private void init() {
Logger.e(TAG, "init: ");
Logger.e(TAG, "init: getNonce = " + NativeUtils.getNonce());
if (SystemUtils.isMainProcessName(this, android.os.Process.myPid())) {
Logger.initialize(this, BuildConfig.DEBUG);
Logger.setLogLevel(Logger.LogLevel.DEBUG); // 开发阶段记录所有日志
String rootDir = MMKV.initialize(this);
Logger.e(TAG, "mmkv root: " + rootDir);
mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
DeviceManagerService.init(this);
OkHttpManager.init(this);
PushExecutor.init(this);
initJPush();
if (BuildConfig.DEBUG) { // 这两行必须写在init之前否则这些配置在init过程中将无效
ARouter.openLog(); // 打印日志
ARouter.openDebug(); // 开启调试模式(如果在InstantRun模式下运行必须开启调试模式线上版本需要关闭,否则有安全风险)
}
ARouter.init(this); // 尽可能早推荐在Application中初始化
DialogX.init(this);
Logger.e(TAG, "slowInit: ");
Aria.init(this);
CrashReport.initCrashReport(getApplicationContext(), "845e3ed68c", false);
CrashReport.setDeviceId(this, Build.MODEL);
xcrash.XCrash.init(this);
AppManager.init(this);
MapManager.init(this);
MapManager.getInstance().initMap();
MapManager.getInstance().startLocation();
WeatherManager.init(this);
IconCacheManager.init(this);
SherpaOnnxTtsManager.getInstance().init(this);
AlarmManagerHelper.rescheduleAllAlarms(this);
if (mMMKV.decodeInt(CommonConfig.HOURLY_CHIME_ENABLE, 0) == 1) {
HourlyChimeManager.startChime(this);
}
registerReceivers();
// 启动时异步清理磁盘缓存(过期淘汰 + 容量上限),不阻塞启动
CacheManager.getInstance(this).cleanupAsync();
}
}
private void initJPush() {
/*jpush start*/
JPushInterface.setDebugMode(true);
// 调整点一调用启用推送业务功能代码前增加setAuth调用
boolean isPrivacyReady = true; // app根据是否已弹窗获取隐私授权来赋值
if (!isPrivacyReady) {
// JCore 5.0.4之前版本需要显式设置false
if (JCoreInterface.getJCoreSDKVersionInt() < 504) { // 5.0.4版本号对应504
JCollectionAuth.setAuth(this, false);
}
// 所有版本在未授权时都不应初始化SDK
return;
}
JPushInterface.init(this);
JPushInterface.setAlias(this, 0, DeviceManagerService.getInstance().getSerial());
// 调整点二App用户同意了隐私政策授权并且开发者确定要开启推送服务后调用
// JCore 5.0.4+会自动处理授权状态可不需要显式设置true
JCollectionAuth.setAuth(this, true);
/*jpush end*/
Logger.e(TAG, "initJPush: inited JPush");
}
private void catchException() {
Thread.setDefaultUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
Logger.e("捕获异常子线程:", Thread.currentThread().getName() +
"在:" + e.getStackTrace()[0].getClassName());
}
}
);
//下面是新增方法!
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
while (true) {
try {
Looper.loop(); //会先执行这个方法,然后在执行下面的异常捕获方法!
} catch (Exception e) {
Logger.e("捕获异常主线程:", Thread.currentThread().getName() + "在:" + e.getStackTrace()[0].getClassName());
e.printStackTrace();
}
}
}
});
}
private void registerReceivers() {
registerAppChangedReceive();
}
@Deprecated
private void unregisterReceivers() {
if (mAppChangedReceiver != null) {
unregisterReceiver(mAppChangedReceiver);
}
}
private AppChangedReceiver mAppChangedReceiver;
private void registerAppChangedReceive() {
if (null == mAppChangedReceiver) {
mAppChangedReceiver = new AppChangedReceiver();
}
IntentFilter filter = new IntentFilter();
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
filter.addAction(Intent.ACTION_PACKAGE_INSTALL);
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
filter.addAction(Intent.ACTION_MY_PACKAGE_REPLACED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addAction(SystemIntentAction.ACTION_PACKAGE_ENABLE_ROLLBACK);
filter.addAction(SystemIntentAction.ACTION_CANCEL_ENABLE_ROLLBACK);
filter.addAction(SystemIntentAction.ACTION_ROLLBACK_COMMITTED);
filter.addDataScheme("package");
registerReceiver(mAppChangedReceiver, filter);
// 监听系统语言切换,刷新桌面应用名称(该广播不带 package data需单独注册
IntentFilter localeFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
registerReceiver(mAppChangedReceiver, localeFilter);
}
}

View File

@@ -0,0 +1,61 @@
package com.ttstd.controlled.base;
import android.content.Intent;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
import androidx.lifecycle.ViewModelStore;
import androidx.lifecycle.ViewModelStoreOwner;
import com.ttstd.controlled.base.rx.BaseRxService;
import org.jetbrains.annotations.NotNull;
/**
* Service 基类。
*
* 同时实现 LifecycleOwner 与 ViewModelStoreOwner
* - LifecycleOwner 让 LiveData.observe(this, ...) 可用;
* - ViewModelStoreOwner 让 ViewModelProvider 创建的 ViewModel 在 onDestroy
* 时收到 onCleared 回调,从而自动 dispose 其中的网络请求。
*/
public abstract class BaseService extends BaseRxService implements LifecycleOwner, ViewModelStoreOwner {
private final LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
private final ViewModelStore viewModelStore = new ViewModelStore();
@NotNull
@Override
public Lifecycle getLifecycle() {
return lifecycleRegistry;
}
@NotNull
@Override
public ViewModelStore getViewModelStore() {
return viewModelStore;
}
@Override
public void onCreate() {
super.onCreate();
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
//修补在Service中LiveData不能触发
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
// 触发 ViewModel.onCleared(),取消所有在途请求
viewModelStore.clear();
}
}

View File

@@ -1,10 +0,0 @@
package com.ttstd.controlled.base;
import androidx.lifecycle.ViewModel;
public class BaseViewModel extends ViewModel {
@Override
protected void onCleared() {
super.onCleared();
}
}

View File

@@ -1,4 +1,4 @@
package com.ttstd.controlled.base;
package com.ttstd.controlled.base.mvvm;
import android.os.Bundle;

View File

@@ -0,0 +1,57 @@
package com.ttstd.controlled.base.mvvm;
import androidx.lifecycle.ViewModel;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Consumer;
/**
* ViewModel 基类。
*
* 内置 CompositeDisposable所有网络请求通过 {@link #execute} 订阅,
* ViewModel 销毁Activity finish / Service stop时统一 dispose
* 从而实现请求随生命周期自动取消,杜绝内存泄漏与野线程回调。
*/
public class BaseViewModel extends ViewModel {
private final CompositeDisposable disposables = new CompositeDisposable();
/** 注册一个 Disposable交由本 ViewModel 生命周期托管。 */
protected void addDisposable(Disposable disposable) {
if (disposable != null) {
disposables.add(disposable);
}
}
/**
* 订阅一个 Single 并自动切回主线程,结果与异常都在主线程回调。
*/
protected <T> void execute(Single<T> single, Consumer<T> onSuccess, Consumer<Throwable> onError) {
addDisposable(single
.observeOn(io.reactivex.rxjava3.android.schedulers.AndroidSchedulers.mainThread())
.subscribe(onSuccess, onError));
}
/**
* 订阅一个 Observable 并自动切回主线程。
*/
protected <T> void execute(Observable<T> observable, Consumer<T> onNext, Consumer<Throwable> onError) {
addDisposable(observable
.observeOn(io.reactivex.rxjava3.android.schedulers.AndroidSchedulers.mainThread())
.subscribe(onNext, onError));
}
/** 主动清空当前所有订阅(不影响后续再次订阅)。 */
protected void clearDisposables() {
disposables.clear();
}
@Override
protected void onCleared() {
disposables.clear();
super.onCleared();
}
}

View File

@@ -0,0 +1,94 @@
package com.ttstd.controlled.base.rx;
import android.os.Bundle;
import androidx.annotation.CallSuper;
import androidx.annotation.CheckResult;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.trello.rxlifecycle4.LifecycleProvider;
import com.trello.rxlifecycle4.LifecycleTransformer;
import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.ActivityEvent;
import com.trello.rxlifecycle4.android.RxLifecycleAndroid;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.subjects.BehaviorSubject;
/**
* {@link com.trello.rxlifecycle4.components.RxActivity}
* copied form RxActivity}
*/
public abstract class BaseRxActivity extends AppCompatActivity implements LifecycleProvider<ActivityEvent> {
private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();
public BehaviorSubject<ActivityEvent> getLifecycleSubject() {
return lifecycleSubject;
}
@Override
@NonNull
@CheckResult
public final Observable<ActivityEvent> lifecycle() {
return lifecycleSubject.hide();
}
@Override
@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindUntilEvent(@NonNull ActivityEvent event) {
return RxLifecycle.bindUntilEvent(lifecycleSubject, event);
}
@Override
@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindToLifecycle() {
return RxLifecycleAndroid.bindActivity(lifecycleSubject);
}
@Override
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lifecycleSubject.onNext(ActivityEvent.CREATE);
}
@Override
@CallSuper
protected void onStart() {
super.onStart();
lifecycleSubject.onNext(ActivityEvent.START);
}
@Override
@CallSuper
protected void onResume() {
super.onResume();
lifecycleSubject.onNext(ActivityEvent.RESUME);
}
@Override
@CallSuper
protected void onPause() {
lifecycleSubject.onNext(ActivityEvent.PAUSE);
super.onPause();
}
@Override
@CallSuper
protected void onStop() {
lifecycleSubject.onNext(ActivityEvent.STOP);
super.onStop();
}
@Override
@CallSuper
protected void onDestroy() {
lifecycleSubject.onNext(ActivityEvent.DESTROY);
super.onDestroy();
}
}

View File

@@ -0,0 +1,123 @@
package com.ttstd.controlled.base.rx;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.CallSuper;
import androidx.annotation.CheckResult;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import com.trello.rxlifecycle4.LifecycleProvider;
import com.trello.rxlifecycle4.LifecycleTransformer;
import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.FragmentEvent;
import com.trello.rxlifecycle4.android.RxLifecycleAndroid;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.subjects.BehaviorSubject;
/**
* {@link com.trello.rxlifecycle4.components.RxFragment}
* copied form RxFragment}
*/
public class BaseRxDialogFragment extends DialogFragment implements LifecycleProvider<FragmentEvent> {
private final BehaviorSubject<FragmentEvent> lifecycleSubject = BehaviorSubject.create();
public BehaviorSubject<FragmentEvent> getLifecycleSubject() {
return lifecycleSubject;
}
@Override
@NonNull
@CheckResult
public final Observable<FragmentEvent> lifecycle() {
return lifecycleSubject.hide();
}
@Override
@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindUntilEvent(@NonNull FragmentEvent event) {
return RxLifecycle.bindUntilEvent(lifecycleSubject, event);
}
@Override
@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindToLifecycle() {
return RxLifecycleAndroid.bindFragment(lifecycleSubject);
}
@Override
@CallSuper
public void onAttach(android.app.Activity activity) {
super.onAttach(activity);
lifecycleSubject.onNext(FragmentEvent.ATTACH);
}
@Override
@CallSuper
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lifecycleSubject.onNext(FragmentEvent.CREATE);
}
@Override
@CallSuper
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
lifecycleSubject.onNext(FragmentEvent.CREATE_VIEW);
}
@Override
@CallSuper
public void onStart() {
super.onStart();
lifecycleSubject.onNext(FragmentEvent.START);
}
@Override
@CallSuper
public void onResume() {
super.onResume();
lifecycleSubject.onNext(FragmentEvent.RESUME);
}
@Override
@CallSuper
public void onPause() {
lifecycleSubject.onNext(FragmentEvent.PAUSE);
super.onPause();
}
@Override
@CallSuper
public void onStop() {
lifecycleSubject.onNext(FragmentEvent.STOP);
super.onStop();
}
@Override
@CallSuper
public void onDestroyView() {
lifecycleSubject.onNext(FragmentEvent.DESTROY_VIEW);
super.onDestroyView();
}
@Override
@CallSuper
public void onDestroy() {
lifecycleSubject.onNext(FragmentEvent.DESTROY);
super.onDestroy();
}
@Override
@CallSuper
public void onDetach() {
lifecycleSubject.onNext(FragmentEvent.DETACH);
super.onDetach();
}
}

View File

@@ -0,0 +1,123 @@
package com.ttstd.controlled.base.rx;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.CallSuper;
import androidx.annotation.CheckResult;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.trello.rxlifecycle4.LifecycleProvider;
import com.trello.rxlifecycle4.LifecycleTransformer;
import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.FragmentEvent;
import com.trello.rxlifecycle4.android.RxLifecycleAndroid;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.subjects.BehaviorSubject;
/**
* {@link com.trello.rxlifecycle4.components.RxFragment}
* copied form RxFragment}
*/
public class BaseRxFragment extends Fragment implements LifecycleProvider<FragmentEvent> {
private final BehaviorSubject<FragmentEvent> lifecycleSubject = BehaviorSubject.create();
public BehaviorSubject<FragmentEvent> getLifecycleSubject() {
return lifecycleSubject;
}
@Override
@NonNull
@CheckResult
public final Observable<FragmentEvent> lifecycle() {
return lifecycleSubject.hide();
}
@Override
@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindUntilEvent(@NonNull FragmentEvent event) {
return RxLifecycle.bindUntilEvent(lifecycleSubject, event);
}
@Override
@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindToLifecycle() {
return RxLifecycleAndroid.bindFragment(lifecycleSubject);
}
@Override
@CallSuper
public void onAttach(android.app.Activity activity) {
super.onAttach(activity);
lifecycleSubject.onNext(FragmentEvent.ATTACH);
}
@Override
@CallSuper
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lifecycleSubject.onNext(FragmentEvent.CREATE);
}
@Override
@CallSuper
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
lifecycleSubject.onNext(FragmentEvent.CREATE_VIEW);
}
@Override
@CallSuper
public void onStart() {
super.onStart();
lifecycleSubject.onNext(FragmentEvent.START);
}
@Override
@CallSuper
public void onResume() {
super.onResume();
lifecycleSubject.onNext(FragmentEvent.RESUME);
}
@Override
@CallSuper
public void onPause() {
lifecycleSubject.onNext(FragmentEvent.PAUSE);
super.onPause();
}
@Override
@CallSuper
public void onStop() {
lifecycleSubject.onNext(FragmentEvent.STOP);
super.onStop();
}
@Override
@CallSuper
public void onDestroyView() {
lifecycleSubject.onNext(FragmentEvent.DESTROY_VIEW);
super.onDestroyView();
}
@Override
@CallSuper
public void onDestroy() {
lifecycleSubject.onNext(FragmentEvent.DESTROY);
super.onDestroy();
}
@Override
@CallSuper
public void onDetach() {
lifecycleSubject.onNext(FragmentEvent.DETACH);
super.onDetach();
}
}

View File

@@ -0,0 +1,56 @@
package com.ttstd.controlled.base.rx;
import android.app.Service;
import androidx.annotation.CheckResult;
import androidx.annotation.NonNull;
import com.trello.rxlifecycle4.LifecycleProvider;
import com.trello.rxlifecycle4.LifecycleTransformer;
import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.ActivityEvent;
import com.trello.rxlifecycle4.android.RxLifecycleAndroid;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.subjects.BehaviorSubject;
public abstract class BaseRxService extends Service implements LifecycleProvider<ActivityEvent> {
private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();
public BehaviorSubject<ActivityEvent> getLifecycleSubject() {
return lifecycleSubject;
}
@Override
@NonNull
@CheckResult
public final Observable<ActivityEvent> lifecycle() {
return lifecycleSubject.hide();
}
@Override
@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindUntilEvent(@NonNull ActivityEvent event) {
return RxLifecycle.bindUntilEvent(lifecycleSubject, event);
}
@Override
@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindToLifecycle() {
return RxLifecycleAndroid.bindActivity(lifecycleSubject);
}
@Override
public void onCreate() {
super.onCreate();
lifecycleSubject.onNext(ActivityEvent.CREATE);
}
@Override
public void onDestroy() {
super.onDestroy();
lifecycleSubject.onNext(ActivityEvent.DESTROY);
}
}

View File

@@ -0,0 +1,6 @@
package com.ttstd.controlled.config;
public class CommonConfig {
public static final String MMKV_ID = "InterProcessKV";
}

View File

@@ -0,0 +1,60 @@
package com.ttstd.controlled.service;
import android.util.Log;
import androidx.lifecycle.ViewModel;
import com.trello.rxlifecycle4.LifecycleTransformer;
import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.ActivityEvent;
import com.ttstd.dialer.bean.BaseResponse;
import com.ttstd.dialer.bean.req.SnLocationReq;
import com.ttstd.dialer.network.BaseObserver;
import com.ttstd.dialer.network.OkHttpManager;
import io.reactivex.rxjava3.subjects.BehaviorSubject;
public class ScreenCaptureModel extends ViewModel {
private static final String TAG = "MainServiceModel";
private BehaviorSubject<ActivityEvent> lifecycleSubject;
// 设置Service生命周期Subject
public void setLifecycleSubject(BehaviorSubject<ActivityEvent> lifecycleSubject) {
this.lifecycleSubject = lifecycleSubject;
}
// 绑定请求到Service销毁事件自动取消请求
private <T> LifecycleTransformer<T> bindToLifecycle() {
if (lifecycleSubject == null) {
throw new IllegalStateException("请先设置LifecycleSubject");
}
return RxLifecycle.bindUntilEvent(lifecycleSubject, ActivityEvent.DESTROY);
}
@Override
protected void onCleared() {
super.onCleared();
// 清空生命周期引用,防止内存泄漏
this.lifecycleSubject = null;
}
public void uploadLocation(SnLocationReq locationReq) {
Log.e(TAG, "uploadLocation: ");
OkHttpManager.getInstance().getUploadLocationObservable(locationReq)
.compose(bindToLifecycle())
.subscribe(new BaseObserver<BaseResponse>() {
@Override
public void onSuccess(BaseResponse baseResponse) {
Log.e("uploadLocation", "onSuccess: " + baseResponse);
}
@Override
public void onFailure(Throwable e) {
Log.e("uploadLocation", "onFailure: " + e.getMessage());
}
});
}
}