Android RxJava生命周期管理解决方案整理

2023-10-30

一、为什么要做生命周期管理?

Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> emitter) throws Exception {
        //TODO
    }
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<String>() {
    @Override
    public void accept(String str) throws Exception {
        
    }
});

这样就是一个简单的异步处理,但是如果只是这样使用肯定是不行,因为在 Android 开发过程中,如果在进行耗时操作的时候,操作还没有结束,这个时候退出的当前 Activity,这个时候,这段代码的处理并不会因为 Activity 的退出而结束,就会导致内存泄漏等问题,严重的时候甚至会导致 APP 闪退。

二、如何管理生命周期?
1、使用CompositeDisposable 这个类,手动实现对 RxJava 的管理
原理:每次使用 RxJava,都将其生成的 Disposable 对象添加到 CompositeDisposable 对象中,并在每个界面结束(onDestroy)的时候,调用 CompositeDisposable 对象的 clear()方法取消事件。

实现过程:1.实现一个统一管理的基准类

public class CommonComposite {
 
    private CompositeDisposable mCompositeDisposable;
 
    public void addDisposable(Disposable disposable) {
        if (mCompositeDisposable == null || mCompositeDisposable.isDisposed()) {
            mCompositeDisposable = new CompositeDisposable();
        }
        mCompositeDisposable.add(disposable);
    }
 
    public void unDisposable() {
        if (mCompositeDisposable != null) {
            mCompositeDisposable.dispose();
        }
    }
}


2.在每次使用RxJava时,在最后的订阅subscribe之前,统一添加doOnSubscribe()方法,并在里面调用上面的addDisposable(),如下:

RetrofitClient.get()
        .invoke(CommandId.CASH_OUT_APPLY_LIST, params.toString())
        .doOnSubscribe(new Consumer<Disposable>() {
            @Override
            public void accept(Disposable disposable) throws Exception {
                addDisposable(disposable);
            }
        })
        .subscribe(new CommonObserver<CashOutApplyList>() {
            @Override
            public void onSuccess(CashOutApplyList data) {
                mView.updateCashOutApplyList(data.getRows());
            }
 
            @Override
            public void onError(String msg, String code) {
                mView.updateCashOutApplyList(msg);
            }
        });


3.在页面销毁的回调方法中(如onDestroy)中调用unDisposable()进行取消事件订阅

@Override
protected void onDestroy() {
    if( mPresenter!=null){
        mPresenter.unsubscribe();
    }
    super.onDestroy();
}
@Override
public void unsubscribe() {
    unDisposable();
}


2、使用RxLifecycle
Github:https://github.com/trello/RxLifecycle

实现过程:1.添加依赖

implementation 'com.trello.rxlifecycle2:rxlifecycle:2.2.1'
implementation 'com.trello.rxlifecycle2:rxlifecycle-android:2.2.1'
implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.1'
2.继承容器类

Activity/Fragment 需要继承 RxAppCompatActivity/RxFragment,主要支持如下几种容器类:

只需要在项目中针对base类的容器中继承实现对应的Rx类即可,这一步主要是对生命周期的回调事件进行监听。

3.绑定容器生命周期

以Activity为例,主要有如下两种方法(Fragment也有同样的两种方法,只是方法名会有所不同):

bindUntilEvent(@NonNull ActivityEvent event) 
 
bindToLifecycle()
(1)bindUntilEvent(@NonNull ActivityEvent event)

//该方法指定在哪个生命周期方法调用时取消订阅

其中ActivityEvent是一个枚举类,对应于Activity的生命周期

public enum ActivityEvent {
    CREATE,
    START,
    RESUME,
    PAUSE,
    STOP,
    DESTROY
}
使用如下:指定在生命周期onDestory()时,取消订阅

@SuppressLint("AutoDispose")
    private void test() {
      Observable.interval(1, TimeUnit.SECONDS)
                .doOnDispose(new Action() {
                    @Override
                    public void run() throws Exception {
                        //doOnDispose:当调用 Disposable 的 dispose() 之后回调该方法
                        Log.e(TAG, "=======" + "doOnDispose:" + "=========");
                        Log.e(TAG, "=======" + "doOnDispose,Thread:" + Thread.currentThread().getName() + "=========");
                    }
                })
                .compose(bindUntilEvent(ActivityEvent.DESTROY))//指定在生命周期onDestory()时,取消订阅
                .subscribe(new Observer<Long>() {
 
                    Disposable disposable;
 
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.e(TAG, "=======" + "onSubscribe:" + "=========");
                        disposable = d;
                    }
 
                    @Override
                    public void onNext(Long aLong) {
                        Log.e(TAG, "=======" + "onNext:" + aLong + "=========");
                        Log.e(TAG, "=======" + "onNext,Thread:" + Thread.currentThread().getName() + "=========");
                    }
 
                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, "=======" + "onError:" + "=========");
                    }
 
                    @Override
                    public void onComplete() {
                        Log.e(TAG, "=======" + "onComplete:" + "=========");
                    }
                });
    }

运行结果如下:

(2)使用bindToLifecycle()

//在某个生命周期进行绑定,在对应的生命周期进行订阅解除。具体的对应关系如下:

使用如下:在生命周期onStart()时进行绑定(就是test2()方法放在onStart()中),在onStop()时取消

@SuppressLint("AutoDispose")
    private void test2() {
        Observable.interval(1, TimeUnit.SECONDS)
                .doOnDispose(new Action() {
                    @Override
                    public void run() throws Exception {
                        //doOnDispose:当调用 Disposable 的 dispose() 之后回调该方法
                        Log.e(TAG, "=======" + "doOnDispose:" + "=========");
                        Log.e(TAG, "=======" + "doOnDispose,Thread:" + Thread.currentThread().getName() + "=========");
                    }
                })
                .compose(bindToLifecycle())//在某个生命周期进行绑定,在对应的生命周期进行订阅解除。如在onResume()里调用test2()进行绑定订阅,则在onPause()进行解除订阅,生命周期是两两对应的。
                .subscribe(new Observer<Long>() {
 
                    Disposable disposable;
 
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.e(TAG, "=======" + "onSubscribe:" + "=========");
                        disposable = d;
                    }
 
                    @Override
                    public void onNext(Long aLong) {
                        Log.e(TAG, "=======" + "onNext:" + aLong + "=========");
                        Log.e(TAG, "=======" + "onNext,Thread:" + Thread.currentThread().getName() + "========="); 
                    }
 
                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, "=======" + "onError:" + "=========");
                    }
 
                    @Override
                    public void onComplete() {
                        Log.e(TAG, "=======" + "onComplete:" + "=========");
                    }
                });

运行结果如下:

原理分析:

主要就是:compose、BehaviorSubject、LifecycleTransformer、takeUntil、take、skip、combineLatest这几部分;详细参考 RxLifecycle的使用及原理分析

它的设计思路:

1.在Activity中,定义一个Observable(Subject),在不同的生命周期发射不同的事件;

2.通过compose操作符(内部实际上还是依赖takeUntil操作符),定义了上游数据,当其接收到Subject的特定事件时,取消订阅;

3.Subject的特定事件并非是ActivityEvent,而是简单的boolean,它已经内部通过combineLast操作符进行了对应的转化。

实际上,Subject和ActivityEvent对RxLifecycle的使用者来讲,是对应隐藏的。我们只需要调用它提供给我们的API,而内部的实现者我们无需考虑,但是也只有去阅读和理解了它的思想,我们才能更好的选择使用这个库

3、使用RxAutoDispose(分引入LifeCycle和不引入)
Github:https://github.com/uber/AutoDispose

实现过程:1.添加依赖

implementation 'com.uber.autodispose:autodispose:1.3.0'
implementation 'com.uber.autodispose:autodispose-android-archcomponents:1.3.0'
2.在代码中使用(两种使用方式)

//在Activity或Fragment中使用
.as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this)))//方式一,自动绑定,在哪里注册,那么就在它的对立时期解除绑定
.as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this, Lifecycle.Event.ON_DESTROY)))//方式二:指定解除绑定周期
private void test() {
    Observable.interval(0, 1, TimeUnit.SECONDS)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnDispose(new Action() {
                @Override
                public void run() throws Exception {
                    //doOnDispose:当调用 Disposable 的 dispose() 之后回调该方法
                    Log.e(TAG, "=======" + "doOnDispose:" + "=========");
                    Log.e(TAG, "=======" + "doOnDispose,Thread:" + Thread.currentThread().getName() + "=========");
                }
            })
            //AutoDispose在被订阅时,获取到Activity当前的生命周期,并找到对应需要结束订阅的生命周期事件
            .as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this)))//方式一,自动绑定,在哪里注册,那么就在它的对立时期解除绑定
            .subscribe(new Observer<Long>() {
 
                Disposable disposable;
 
                @Override
                public void onSubscribe(Disposable d) {
                    Log.e(TAG, "=======" + "onSubscribe:" + "=========");
                    disposable = d;
                }
 
                @Override
                public void onNext(Long aLong) {
                    Log.e(TAG, "=======" + "onNext:" + aLong + "=========");
                    Log.e(TAG, "=======" + "onNext,Thread:" + Thread.currentThread().getName() + "=========");
                    textview.setText(String.valueOf(aLong));
                    if (aLong >= 10) {
                        disposable.dispose();
                        Log.e(TAG, "=======" + "dispose" + "=========");//这里会落后于doOnDispose执行
                    }
                }
 
                @Override
                public void onError(Throwable e) {
                    Log.e(TAG, "=======" + "onError:" + "=========");
                }
 
                @Override
                public void onComplete() {
                    Log.e(TAG, "=======" + "onComplete:" + "=========");
                }
            });
}

原理分析:

as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this))

(1)参数this:

就是Activity本身,当然它也可以是Fragment,这个参数对象只有一个要求,就是必须实现LifecycleOwner接口。LifecycleOwner接口是Google Android官方架构组件:Lifecycle的一个重要组件,在androidx中,ComponentActivity实现了这个接口,实现了这个接口的对象都拥有生命周期(Lifecycle)。这意味着,只要是实现了LifecycleOwner的类,都可以作为参数传给AutoDispose,用以控制Observable和组件生命周期的绑定。

(2)如何实现生命周期的绑定

参考RxLifecycle的原理:

1.在Activity中,定义一个Observable(Subject),在不同的生命周期发射不同的事件; 2.通过compose操作符(内部实际上还是依赖takeUntil操作符),定义了上游数据,当其接收到Subject的特定事件时,取消订阅; 3.Subject的特定事件并非是ActivityEvent,而是简单的boolean,它已经内部通过combineLast操作符进行了对应的转化

AutoDispose获取了Activity(LifecycleOwner)对象,并定义了一个新的Observable,在Activity的不同生命周期中,发射对应的事件。

和RxLifecycle很类似的是,AutoDispose在被订阅时,获取到Activity当前的生命周期,并找到对应需要结束订阅的生命周期事件:

private static final CorrespondingEventsFunction<Lifecycle.Event> DEFAULT_CORRESPONDING_EVENTS =
    lastEvent -> {
      switch (lastEvent) {
        case ON_CREATE:
          return Lifecycle.Event.ON_DESTROY;
        case ON_START:
          return Lifecycle.Event.ON_STOP;
        case ON_RESUME:
          return Lifecycle.Event.ON_PAUSE;
        case ON_PAUSE:
          return Lifecycle.Event.ON_STOP;
        case ON_STOP:
        case ON_DESTROY:
        default:
          throw new LifecycleEndedException("Lifecycle has ended! Last event was " + lastEvent);
      }
    };

也就是说,在我们的ObservableA订阅时,就已经知道了自己在Activity的哪个生命周期让AutoDispose内部自定义的ObservableB自动发射事件,ObservableA监听到这个事件时且未dispose,解除订阅避免内存泄漏。

毕竟内存泄漏是少数,更大的可能是ObservableA早就执行完任务dispose了,因此ObservableB实际上就是一个Maybe,类似于

ObservableA.takeUntil( Maybe< true > )

核心代码:

public static <E> CompletableSource resolveScopeFromLifecycle(
    Observable<E> lifecycle, final E endEvent, @Nullable final Comparator<E> comparator) {
  Predicate<E> equalityPredicate;
  if (comparator != null) {
    equalityPredicate = e -> comparator.compare(e, endEvent) >= 0;
  } else {
    equalityPredicate = e -> e.equals(endEvent);
  }
  return lifecycle.skip(1).takeUntil(equalityPredicate).ignoreElements();
}


(3)as方法执行后生成了一个什么?

as方法内部生成了一个AutoDisposeConverter对象,类似于compose,不同的是,Observable通过compose生成的对象还是Observable,但as方法生成的则是一个新的对象:

public final <R> R as(@NonNull ObservableConverter<T, ? extends R> converter)
实际上,抛开复杂的细节,AutoDispose最终将原来的Observable,生成了一个新的AutoDisposeObservable对象, 在执行订阅时,也生成了一个新的AutoDisposingObserverImpl对象

(4)AutoDispose和RxLifecycle的区别

原理相似,但是RxLifecycle有如下局限性:

1、需要继承父类(RxActivity / RxFragment等)

2、如何处处绑定生命周期?

简单的例子,我的RecyclerView的Adapter中订阅了Observable,亦或者,在MVP的架构或者 MVVM架构中,我的presenter或者我的viewModel无法直接获取RxActivity的引用(作为View 层,更应该抽象为一个接口与Presenter进行交互)。 这意味着,想要进行Observable的生命周期绑定,在RecyclerView的Adapter中,我必须要通 过将Activity作为依赖,注入到Adapter中: new ListAdapter(RxActivity activity); 而对于Presenter,我需要对View抽象接口进行instanceof 的判断:

if (view instanceof RxActivity) {

        return bindToLifecycle((RxActivity) view);

}

4、如何把AutoDispose添加到目前的Android项目中
 

(以MVP架构为例)

方式一:

(1)封装Util类

static class RxAutoDisposeUtils {
 
    private RxAutoDisposeUtils() {
    }
 
    public static <T> AutoDisposeConverter<T> bindLifecycle(LifecycleOwner lifecycleOwner) {
        return AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner));
    }
 
    public static <T> AutoDisposeConverter<T> bindLifecycle(LifecycleOwner lifecycleOwner, Lifecycle.Event event) {
        return AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner, event));
    }
 
    public static <T> AutoDisposeConverter<T> bindDestroyLifecycle(LifecycleOwner lifecycleOwner) {
        return AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner, Lifecycle.Event.ON_DESTROY));
    }
}

(2)在BaseActivity/BaseFragment中添加代码

只要持有LifecycleOwner对象,Observable都可以通过RxLifecycleUtils.bindLifecycle(LifecycleOwner)进行绑定

fun <T> bindLifecycle(): AutoDisposeConverter<T> {
        return AutoDispose.autoDisposable<T>(AndroidLifecycleScopeProvider.from(lifecycle))
 
//        return AutoDispose.autoDisposable<T>(
//            AndroidLifecycleScopeProvider.from(
//                lifecycleOwner,
//                Lifecycle.Event.ON_DESTROY
//            )
//        )
    }

(3)在任何BaseActivity的实现类中,我们都可以通过下述代码实现Observable的生命周期绑定

Observable.interval(0, 1, TimeUnit.SECONDS)
        .as(bindLifecycle())
        .subscribe()

(4)在Presenter中通过持有Activity的对象,达到Observable生命周期的绑定(类似RxLifecycle的使用)

public interface BaseView {
    <T> LifecycleTransformer<T> getActivityLifecycleProvider();
    LifecycleOwner getLifecycleOwner();
}
public class RxJavaContract {
    interface View extends BaseView {
        void onNetRequest();
    }
    interface Presenter extends BasePresenter {
        void netRequest();
    }
}

//在BaseActivity中实现如下方法

open fun <T> getActivityLifecycleProvider(): LifecycleTransformer<T> {
//        return bindToLifecycle() //可以绑定Activity生命周期
        return bindUntilEvent(ActivityEvent.DESTROY);//可以绑定Activity生命周期
    }
 
    fun getLifecycleOwner(): LifecycleOwner {
        return this
    }
public class RxJavaPresenter implements RxJavaContract.Presenter {
    private RxJavaContract.View mView;
    Observable.interval(1, TimeUnit.SECONDS)
            .compose(mView.getActivityLifecycleProvider())
            .subscribe()
}

方式二:使用Google官方Lifecycle组件

(1)首先让我们的IPresenter接口实现LifecycleObserver接口

//实现了 LifecycleObserver 接口的类可以和实现了 LifecycleOwner 接口的类无缝工作
//,因为 LifecycleOwner 可以提供一个 Lifecycle 对象,而 LifecycleObserver 就正
//需要对这个 Lifecycle 对象进行监听呢。 LifecycleOwner 是从特定的类(比如
// Activity 或者 Fragment 等)中抽象出来的Lifecycle 的持有者

interface IPresenter : LifecycleObserver {
    //使用Google官方Lifecycle组件
    // 使用注解  @OnLifecycleEvent 来表明该方法需要监听指定的生命周期事件
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun onCreate(@NotNull owner: LifecycleOwner)
 
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun onDestroy(@NotNull owner: LifecycleOwner)
 
    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    fun onLifecycleChanged(@NotNull owner: LifecycleOwner, @NotNull event: Lifecycle.Event)
}

(2)然后在BasePresenter中管理LifecycleOwner

abstract class BaseNewPresenter :
    IPresenter {

    private lateinit var lifecycleOwner: LifecycleOwner
 
    override fun onCreate(owner: LifecycleOwner) {
        Log.e("LifecycleOwner", "=======" + "onCreate:" + "=========")
        this.lifecycleOwner = owner
    }
 
    override fun onDestroy(owner: LifecycleOwner) {
 
    }
 
    override fun onLifecycleChanged(owner: LifecycleOwner, event: Lifecycle.Event) {
 
    }
 
    fun <T> bindLifecycle(): AutoDisposeConverter<T> {
        return AutoDispose.autoDisposable<T>(AndroidLifecycleScopeProvider.from(lifecycleOwner))
 
//        return AutoDispose.autoDisposable<T>(
//            AndroidLifecycleScopeProvider.from(
//                lifecycleOwner,
//                Lifecycle.Event.ON_DESTROY
//            )
//        )
    }
}

(3)最后在Activity中添加Presenter为观察者,观察Activity的生命周期

abstract class BaseNewMvpActivity<P : IPresenter> : BaseNewActivity(){
    lateinit var presenter: P
 
    override fun onCreate(savedInstanceState: Bundle?) {
        presenter = createPresenter()
        //这一行,如此每当Activity发生了对应的生命周期改变,Presenter就会执行
        //对应事件注解的方法
        lifecycle.addObserver(presenter)
        super.onCreate(savedInstanceState)
    }
}

(4)Presenter中的使用

public class RxAutoDisposePresenter extends BaseNewPresenter implements RxAutoDisposeContract.Presenter {
 
    private RxAutoDisposeContract.View mView;
    private Context mContext;
    private String TAG = RxAutoDisposePresenter.class.getSimpleName();
 
    public RxAutoDisposePresenter(Context context, RxAutoDisposeContract.View view) {
        this.mContext = context;
        this.mView = view;
    }
 
    @Override
    public void netRequest() {
        Observable.interval(0, 1, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnDispose(new Action() {
                    @Override
                    public void run() throws Exception {
                        //doOnDispose:当调用 Disposable 的 dispose() 之后回调该方法
                        Log.e(TAG, "=======" + "doOnDispose:" + "=========");
                        Log.e(TAG, "=======" + "doOnDispose,Thread:" + Thread.currentThread().getName() + "=========");
                    }
                })
                .as(bindLifecycle())//方式二:指定解除绑定周期
                .subscribe(new BaseObserver<Long>() {
                    @Override
                    public void onSuccess(Long data) {
                        Log.e(TAG, "=======" + "onSuccess:" + data + "=========");
                        mView.onNetRequest(data);
                    }
 
                    @Override
                    public void onError(String msg, String code) {
                        mView.onNetRequest(Long.parseLong(code));
                    }
                });
    }
}

我们即使在Presenter中,也能任意使用myObservable.as(bindLifecycle()) 方法了,和第一种方式相比,更加灵活。

 

原文链接:https://blog.csdn.net/fitaotao/article/details/117522260

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android RxJava生命周期管理解决方案整理 的相关文章

  • 如何在android中点击画布上绘制的圆圈?

    我正在开发一个人脸检测应用程序 在这个应用程序中 我必须在脸上的眼睛和嘴巴用户可以点击拖动圆圈 在检测到的人脸上根据自己设置位置 因此 所有圆圈都已成功绘制在脸上 但我无法单击特定圆圈并使用缩小选项在整个脸上移动 请建议我有关相同问题的正确
  • 如何在 StateListDrawable 中设置可绘制对象的 alpha 值?

    我想在按下时更改可绘制对象的 alpha 值 因此 我创建了两个可绘制对象并将它们放入 StateListDrawable 中 并设置按下状态的 alpha 值 但它就是行不通 StateListDrawable content new S
  • 如何检测android中的颠倒方向?

    在我的 Android 应用程序中 我有全景图像 并且我使用 TYPE ORIENTATION 传感器根据手机运动旋转该图像 它对于横向和纵向都工作良好 这是旋转逻辑的代码 Override public void onSensorChan
  • 任务“:app:checkReleaseDuplicateClasses”执行失败

    我的 React Native Android 构建中突然出现构建问题 令人惊讶的是 它是早上建好的 没有做任何改变 但突然就失败了 这就是我得到的错误 知道为什么会发生这种情况吗 在 stack 和 GitHub 中也看到了一些类似的问题
  • ActionBarCompat 支持库 android:selectableItemBackground 不起作用

    我正在使用新的 ActionBarCompat 支持库 操作栏中的操作按钮在按下时应更改其背景 它适用于 Android 4 3 但不适用于 Gingerbread 在姜饼中 如果我按下按钮 它不会改变背景 我什至改变了选择器 它再次适用于
  • 相当于Android中的javax.swing.Timer

    有没有类似的东西javax swing Timer在安卓上 我知道如何创建自己的线程 但是有类似摆动计时器的东西吗 您可能正在寻找课程android os CountDownTimer http developer android com
  • 如何在 Android 中创建刮刮卡?

    我需要为我在学校的期末项目创建一个 刮刮卡 应用程序 但找不到如何实现刮刮事件的方法 如何创建背景图像并在其上放置灰色矩形 所以当我刮刮这些矩形时我会看到他们下面的图片 实现必须在 Android 中 因为我还不知道如何在 Objectiv
  • Android 上的硬币识别

    我目前正在开发一个 Android 应用程序 它能够拍摄硬币的现有图像 或者使用内置摄像头扫描单个硬币 非常像 Google Goggles 我正在使用 Android 版 OpenCV 我的问题如下 什么方法最适合使用 OpenCV 在
  • 从Asynctask返回结果

    如果我的 Android 应用程序中有这个后台工作文件 并且它从我的数据库获取数据 我如何将字符串 结果 传递给另一个类 后台工作人员连接到我的服务器 然后使用 php 连接到数据库 public class BackgroundWorke
  • 注销时Firebase facebook按钮android身份验证

    我在我的 Android 应用程序中使用 firebase 并在 facebook SDK 中使用登录 我面临的唯一问题是 当我使用 facebook 登录然后注销时 facebook 登录按钮处于 注销 状态 当我单击它时 它会询问我是否
  • Twitter 集成期间获取访问令牌函数行为不当

    我只是想使用 twitter4j 从我的 Android 应用程序向 Twitter 分享文本 首先 我尝试的是我创建了一个新项目 并且这个特定的代码运行成功 然后我在我的应用程序中混合了该特定代码 登录 Twitter 成功完成 之后我发
  • Android接收通知打开和取消事件

    我从 webService 接收数据以生成自定义通知 我想追踪Intent要知道open 点击 或cancel 滑动 通知上的事件 以报告服务器进行分析 有没有听众onIntentStart or onIntentCanceled 也许是通
  • 来自外部 XML 的 Android 本地化

    是否可以使用从服务接收到的 XML 在运行时翻译 Android 应用程序 如果可能的话 请有人指出我正确的方向 谢谢 Warning 我读到的所有内容都表明 让您的应用程序更改语言不是一个好主意 因为 Android 框架不支持它 并且可
  • 我可以使用“导入 com.facebook.FacebookSdk;”使用 Facebook SDK 3.23.1?

    在我的 app build gradle 文件中 我有compile com facebook android facebook android sdk 3 23 1 在我的 BaseActivity java 文件 其中有 public
  • Android 依赖项:apklib 与 aar 文件

    据我了解 apklib包含代码 共享资源Maven aar文件由以下人员分发Gradle The aar与 apklib 的主要区别在于 类被编译并包含在 aar 根目录下的classes jar 中 然而apklib不能包含已编译的类文件
  • Android - 内容值覆盖现有行

    我正在尝试使用插入值ContentValues 我已将 5 个值插入到 5 列中 运行应用程序后 我只有最后一组值的行ContentValues 前四组未插入 ContentValues cv new ContentValues cv pu
  • 如何使用 onSearchRequested() 调用搜索对话框

    我正在尝试实现搜索对话框 但无法显示活动中的搜索 我在清单文件中定义了主要活动 此活动向用户显示了他们必须从中选择的选项列表 选项之一是 搜索 选项
  • RecyclerView元素更新+异步网络调用

    我有一个按预期工作的回收视图 我的布局中有一个按钮可以填充列表 该按钮应该进行异步调用 根据结果 我更改按钮的外观 这一切都发生得很好 但是 当我单击按钮并快速向下滚动列表时 异步调用的结果会更新新视图的按钮 代替旧视图的视图 我该如何处理
  • Android:列“_id”不存在

    我收到这个错误 IllegalArgumentException 列 id 不存在 当使用SimpleCursorAdapter从我的数据库中检索 该表确实有这个 id柱子 注意到这是一个常见问题 我尝试根据网上的一些解决方案来解决它 但它
  • Android 中带有无尽列表视图滚动的 AsyncTask

    我正在创建一个应用程序 其中我需要有无限的滚动列表视图 我不想在我的应用程序中使用任何库 我在网上看到了一些有助于实现此类列表视图的示例 但我的疑问是 当我的数据来自服务器并在异步任务中进行解析时 如何才能拥有无尽的列表视图 如何从滚动异步

随机推荐

  • Service Intent must be explicit的解决方法

    http blog csdn net shenzhonglaoxu article details 42708723 java view plain copy final Intent intent new Intent intent se
  • jeesite框架中获取登入用户的登入名

    jeesite框架中获取登入用户的登入名 UserUtils getUserName
  • 17 张图实战 + 理清 K8S 网络排错思路,硬核!

    作者 Cylon出处 https u kubeinfo cn R35JNc Overview 本文将引入一个思路 在 Kubernetes 集群发生网络异常时如何排查 文章将引入 Kubernetes 集群中网络排查的思路 包含网络异常模型
  • 算法笔记之旅——问题B:出租车费

    题目描述 某市出租车计价规则如下 起步4公里10元 即使你的行程没超过4公里 接下来的4公里 每公里2元 之后每公里2 4元 行程的最后一段即使不到1公里 也当作1公里计费 一个乘客可以根据行程公里数合理安排坐车方式来使自己的打车费最小 例
  • 空间误差分析:统一的应用导向处理(Matlab代码实现)

    个人主页 研学社的博客 欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现 1 概述 本文关
  • SVN软件中patch的的运用以及patch介绍

    什么是patch patch就是补丁 在程序中就是和原来相比有差异的部分 生活中常见的就是程序升级 假设我们用手机下载某个软件显示是100M大小 第一次安装时就需要下载100M大小的安装包 当安装完成后 后续会收到软件升级的提醒 升级包可能
  • Vuforia提高识别图星级

    本文转载自http blog csdn net unity3d xyz article details 50638007 高通的识别图上传到后台以后我们可以看有星级评定 星值最大为5星 星值越大有以下好处 1 识别图越容易识别 2 识别出来
  • 从零开始的RVOS: Referring Video Object Segmentation

    最近新接触到一个与VOS相关的任务 叫做Referring VOS 该任务基于文本描述对视频中特定目标进行分割 是一个新兴的跨模态CV任务 数据集 1 静态推断图像分割数据集 虽然RVOS是视频任务 但根据以往的经验和相关文章的方法 可以使
  • 水文模型有哪些?SWAT模型、VIC模型、HEC模型、HSPF模型、HYPE模型、SWMM模型、FVCOM模型、Delft3D模型等应用

    目录 从小白到精通SWAT模型学习建模方法 实例应用 高级进阶 R VIC模型融合实践技术应用及未来气候变化模型预测 HEC RAS一维 二维建模方法及实践技术应用 HEC HMS水文模型实践技术应用 HSPF 模型应用 HYPE分布式水文
  • Service的两种启动方式

    在Android开发的过程中 Service是一个非常重要的组件 它的生命周期里面有几个特别重要的方法 Service的生命周期 onCreate 当服务创建的时候调用 onStartCommand startServcie的时候会调用这个
  • RFID作业(第三次)

    1 通信系统中为什么要进行编码和解码 常见的编码方法有哪些 信源编码是指将模拟信号转换成数字信号 或将数字信号编码成更合适传输的数字信号 换句话来说 通信系统编码和解码是为了让信号更适合传输 常见的编码方法有1 反向不归零编码 2 曼彻斯特
  • ListView的复用问题,点击条目变色.不复用

    主要的是3个类 包含activity application 和一个adpter 内部的细节在代码中都有详细的注释 可以参考 application public class MyApplication extends Applicatio
  • PyQt5学习笔记16----PyQt信号和槽传递额外参数

    使用Pyqt编程过程中 经常会遇到给槽函数传递额外参数的情况 但是信号 槽机制只是指定信号如何连接到槽 信号定义的参数被传递给槽 而额外的参数 用户定义 不能直接传递 而传递额外参数又是很有用处 你可能使用一个槽处理多个组件的信号 有时要传
  • GIT实战篇,教你如何使用GIT可视化工具

    系列文章目录 手把手教你安装Git 萌新迈向专业的必备一步 GIT命令只会抄却不理解 看完原理才能事半功倍 快速上手GIT命令 现学也能登堂入室 GIT实战篇 教你如何使用GIT可视化工具 系列文章目录 一 GIT有哪些常用工具 1 Git
  • 图像增强 数据增强

    目录 python opncv 数据增强 亮度 opencv 亮度饱和度增强 vgg19图像增强 c opencv 图像增强 python opncv 数据增强 亮度 def data augment image brightness fa
  • 从零开始的python教程:全面又好用的学习资料

    1 耳熟能详的Python自学网站 廖雪峰python学习网站 推荐理由 全面成体系的python学习内容 概括起来其实就是免费且全面 而且里面的知识讲解也十分恰当 所举的例子也十分的形象 不足 知识之间的梯度对于刚学习python的学习者
  • 浅谈:VS中解决Bug的几个简单实用调试技巧

    在写这篇文章之前 就已经有不少读者来问我 有没有调试方面的文章 给推荐 思前想后 笔者决定自己研究一下调试的技巧 以便更好的使用VS 对于现在不少初学C语言的学者 大部分开始使用VS2019 或者VS2022 但是对于代码出现了错误 该怎么
  • Idea运行springboot项目(保姆级教学)

    大家好 我是CZ淡陌 一名专注以理论为基础实战为主的技术博主 将再这里为大家分享优质的实战项目 本人在Java毕业设计领域有多年的经验 陆续会更新更多优质的Java实战项目 希望你能有所收获 少走一些弯路 向着优秀程序员前行 Java项目精
  • 一、深入理解redis之需要掌握的知识点

    导读 从本章开始我们将要深入讲解redis 讲解的内容包括 redis的基础数据类型及应用场景 数据存储 持久化方式 RDB AOF redis集群进化过程 redis中AKF问题解决方案 redis中CAP问题解决方案 redis的分布式
  • Android RxJava生命周期管理解决方案整理

    一 为什么要做生命周期管理 Observable create new ObservableOnSubscribe