Skip to content

How to code the MVP in Android

  • 这是一个缩略版的MVP结构,实际上,还可以注入更多的生命周期内容,因为这里只是为了简单介绍MVP的模式,在实际开发过程中,我们很少会再去使用这种开发模式了,所以这里就不详细讲了。
  • 当然如果能借助AutoService,使用可以变得更加方便。(不过,这直接上MVVM就行了)

MVP with Kotlin

kotlin
interface IContract {
    interface IViewRender {
        fun callback(message: String)
    }

    interface IPresenter {
        fun fetchData()

        fun onDestroy()
    }
}

class View : IContract.IViewRender {
    private val presenter: Presenter = Presenter(this)
    
    override fun onViewCreated() {
        presenter.fetchData()
    }

    override fun onDestroy() {
        // 取消Presenter的网络请求
        presenter.onDestroy()
    }

    override fun callback(message: String) {
        mBinding.tvInfo.text = message
    }
}

// Presenter
class Presenter(
    val viewRender: IContract.IViewRender,
): IContract.IPresenter {    
    private val mCompositeDisposable = CompositeDisposable()

    override fun fetchData() {
        Single.create<String>(object : SingleOnSubscribe<String> {
            override fun subscribe(emitter: SingleEmitter<String?>) {
                Thread.sleep(2000L) // 假装这是一个耗时操作
                emitter.onSuccess("Hello World")
            }
        }).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object: SingleObserver<String> {
                override fun onSubscribe(disposable: Disposable) = {
                    mCompositeDisposable.add(disposable)
                }
                
                override fun onSuccess(result: String) {
                    viewRender.callback(result)
                }

                override fun onError(e: Throwable) = Unit
            })
    }

    override fun onDestroy() {
        mCompositeDisposable.clear()
    }
}
  • 实际上,这里的意思就是使用Activity/Fragment的生命周期中的销毁时机去取消网络请求,防止callback向生命周期已经销毁但对象还没有回收的页面去做数据刷新导致可能出现的NullPointException.

MVP with Java

  • 定义契约类
java
public interface IContract {

    public interface IViewRender {
        void callback(@NotNull String message);
    }

    public interface IPresenter {
        void fetchData();

        void onDestroy();
    }
}
  • 实现View层的UI回调以及对View与Presenter之间生命周期的绑定
java
public BussinessFragment extends Fragment implements IContract.IViewRender {

    private final Presneter presenter = new Presenter(this);

    @Override
    public void onViewCreated() {
        presenter.fetchData();
    }

    @Override
    public void onDestroy() {
        presenter.onDestroy();
    }

    @Override
    public void callback(@NotNull String message) {
        mBinding.tvInfo.setText(message);
    }
}
  • 实现Presenter
java
public BussinessPresenter implements IContract.IPresenter {

    @NotNull
    private final CompositeDisposable mCompositeDisposable = new CompositeDisposable();

    @NotNull
    private final IContract.IViewRender viewRender;

    public BussinessPresenter(@NotNull IContract.IViewRender viewRender) {
        this.viewRender = viewRender;
    }

    
    @Override
    public void fetchData() {
        Single.create<String>((emitter) -> {
            Thread.sleep(2000L); // 假装这是一个耗时操作
            emitter.onSuccess("Hello World");
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new SingleObserver<String> {
            @Override
            void onSubscribe(disposable: Disposable) {
                mCompositeDisposable.add(disposable);
            }
            
            @Override
            void onSuccess(result: String) {
                viewRender.callback(result);
            }

            @Override
            void onError(e: Throwable) {
                // ignored
            }
        })
    }

    @Override
    public void onDestroy() {
        mCompositeDisposable.clear();
    }
}

随便写写的,喜欢就好。 使用VitePress构建