java - LifecycleRegistry 未初始化,在 MVP 架构的 BaseActivity 中

标签 java android androidx android-lifecycle android-mvp

我为我的 Activity 和 Fragment、Presenter、ViewHolder 和 ViewModel 定义了几个基类,并定义了一个接口(interface)和 Presenter,所有其他继承这些基类的 Activity ,在我的 BaseActivity 类和 BaseFragmentClass 中,我是创建 lifecycleRegistry 对象并对其进行初始化,但当应用程序启动时它崩溃并在 ComponentActivity 的构造函数中返回 null 错误 getLifecycle()。请确保您在第一次调用 getLifecycle() 时延迟构建生命周期,而不是依赖于字段初始化。

文件:BaseFragment.java

package com.example.myapp.data.helper.base;


import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleRegistry;
import androidx.lifecycle.ViewModelProviders;

public abstract class BaseFragment<V extends MvpView, P extends BasePresenter<V>>
        extends Fragment implements MvpView, View.OnClickListener {
    private  final LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
    protected P presenter;
    private int defaultValue = -1;
    private ViewDataBinding viewDataBinding;
    private View rootView;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    @SuppressWarnings("unchecked")
    @CallSuper
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        BaseViewModel<V, P> viewModel = ViewModelProviders.of(this).get(BaseViewModel.class);
        boolean isPresenterCreated = false;
        if (viewModel.getPresenter() == null) {
            viewModel.setPresenter(initPresenter());
            isPresenterCreated = true;
        }
        presenter = viewModel.getPresenter();
        presenter.attachLifecycle(getLifecycle());
        presenter.attachView((V) this);
        if (isPresenterCreated)
            presenter.onPresenterCreated();
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        startUI();
    }

    @Override
    public void onClick(View view) {

    }

    @NonNull
    @Override
    public LifecycleRegistry getLifecycle() {
        return lifecycleRegistry;
    }

    protected abstract void startUI();

    protected abstract void stopUI();

    protected ViewDataBinding getViewDataBinding() {
        return viewDataBinding;
    }

    @CallSuper
    @Override
    public void onDestroyView() {
        super.onDestroyView();

        if (presenter != null) {
            presenter.detachLifecycle(getLifecycle());
            presenter.detachView();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        if (presenter != null) {
            presenter.detachLifecycle(getLifecycle());
            presenter.detachView();
        }

        stopUI();
    }

    private BaseActivity<V,P> getBaseActivity() {
        return ((BaseActivity<V,P>) getActivity());
    }

    private boolean isBaseActivityInstance() {
        return getActivity() instanceof BaseActivity;
    }

    protected void setTitle(String title) {
        if (isBaseActivityInstance()) {
            getBaseActivity().setTitle(title);
        }
    }

    protected void setClickListener(View... views) {
        for (View view : views) {
            view.setOnClickListener(this);
        }
    }

    protected abstract P initPresenter();
}

文件:BaseActivity.java

package com.example.data.helper.base;

import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
import androidx.lifecycle.ViewModelProviders;

public abstract class BaseActivity<V extends MvpView, P extends BasePresenter<V>>
        extends AppCompatActivity implements MvpView, View.OnClickListener, LifecycleOwner {


    private final LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this) ;
    protected P presenter;
    private ViewDataBinding viewDataBinding;
    private Menu menu;
    private int defaultValue = -1;

    @NonNull
    @Override
    public LifecycleRegistry getLifecycle() {
        return lifecycleRegistry;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
        super.onCreate(savedInstanceState, persistentState);
        int layoutId = getLayoutId();
        if (layoutId > defaultValue) {

            try {
                viewDataBinding = DataBindingUtil.setContentView(this, layoutId);
            } catch (Exception e) {
                if (viewDataBinding == null) {
                    setContentView(layoutId);
                }
            }

            BaseViewModel<V,P> viewModel = ViewModelProviders.of(this).get(BaseViewModel.class);
            boolean isPresenterCreated = false;

            if (viewModel.getPresenter() == null) {
                viewModel.setPresenter(initPresenter());
                isPresenterCreated = true;
            }

            presenter = viewModel.getPresenter();
            presenter.attachLifecycle(getLifecycle());
            presenter.attachView((V) this);
            if (isPresenterCreated) {
                presenter.onPresenterCreated();
            }
        }

        startUI();
    }

    @Override
    protected void onResume() {
        super.onResume();
        onResumeUI();
    }
    protected abstract void onResumeUI();
    */

    protected abstract void startUI();

    protected abstract void stopUI();

    protected ViewDataBinding getViewDataBinding() {
        return viewDataBinding;
    }

    protected static void runCurrentActivity(Context context, Intent intent) {
        context.startActivity(intent);
    }

    @Override
    public void onClick(View view) {

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        this.stopUI();
        presenter.detachLifecycle(getLifecycle());
        presenter.detachView();
    }

    protected abstract P initPresenter();

    protected void setTitle(String title) {
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setTitle(title);
        }
    }

    protected void setClickListener(View... views) {
        for (View view : views) {
            view.setOnClickListener(this);
        }
    }

    protected BaseFragment<?, ?> mBaseCurrentFragment;

    protected void commitFragment(int parentId, BaseFragment<?, ?> baseFragment) {
        getSupportFragmentManager()
                .beginTransaction()
                .replace(parentId, baseFragment, baseFragment.getClass().getName())
                .commit();

        setCurrentFragment(baseFragment);
    }

    protected void setCurrentFragment(BaseFragment<?, ?> baseFragment) {
        this.mBaseCurrentFragment = baseFragment;
    }

    protected BaseFragment<?, ?> getBaseCurrentFragment() {
        return mBaseCurrentFragment;
    }
}

**文件:MvpView

public interface MvpView{

}

文件:BasePresenter.java

public abstract class BasePresenter<V extends MvpView> implements LifecycleObserver, Presenter<V> {

    private V myMvpView;
    private Bundle stateBundle;

    @Override
    public void attachView(V mvpView) {
        myMvpView = mvpView;
    }

    @Override
    public void detachView() {
        mMvpView = null;
    }

    @Override
    public void attachLifecycle(Lifecycle lifecycle) {
        if (lifecycle != null) {
            lifecycle.addObserver(this);
        }
    }

    @Override
    public void detachLifecycle(Lifecycle lifecycle) {
        if (lifecycle != null) {
            lifecycle.removeObserver(this);
        }
    }

    public boolean isViewAttached() {
        return myMvpView != null;
    }

    public V getMvpView() {
        return myMvpView;
    }

    public Bundle getStateBundle() {
        return stateBundle == null ?
                stateBundle = new Bundle() : stateBundle;
    }

    public void checkViewAttached() {
        if (!isViewAttached()) throw new MvpViewNotAttachedException();
    }

    public static class MvpViewNotAttachedException extends RuntimeException {
        public MvpViewNotAttachedException() {
            super("Please call Presenter.attachView(MvpView) before" +
                    " requesting data to the Presenter");
        }
    }

    @Override
    public void onPresenterDestroy() {
        if (stateBundle != null && !stateBundle.isEmpty()) {
            stateBundle.clear();
        }
    }
}

更新: 我尝试通过将 lifeCycleRegistry 设置为 Non Final 来更新 BaseActivity.java 和 BaseFragment.java 的代码。并在 getLifecycle 中初始化它(如果它为 null ),但是我只能看到一个空白屏幕,不知道为什么?

public abstract class BaseActivity<V extends MvpView, P extends BasePresenter<V>>
        extends AppCompatActivity implements MvpView, View.OnClickListener {
      private LifecycleRegistry = new LifeCycleRegistry(this);

    @NonNull
    @Override
    public LifecycleRegistry getLifecycle() {
        if (lifecycleRegistry==null){

            lifecycleRegistry= new LifecycleRegistry(this);
        }
        return lifecycleRegistry;
    }

}

所有其他代码相同。

最佳答案

删除对 getLifecycle() 和您自己的 LifecycleRegistry 的覆盖。在 Architecture Components 变得稳定并直接集成到 AppCompatActivity 和 Fragment 之前,这是必需的,但现在不再是必需的。

关于java - LifecycleRegistry 未初始化,在 MVP 架构的 BaseActivity 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62956894/

相关文章:

java - JFreeChart XYSeries 作为字符串

java - Hadoop 中所有节点的公共(public)变量

java - 从 run 方法锁定对另一个类的访问

java - 初学者按钮点击事件

Android Studio :An alert box showed when I try to add RecyclerView

android - 尝试将 AndroidX 迁移到 Android AppCompat

C# 相当于 jar 文件?

java - SharedPreferences 变量无法正常工作

javascript - 如何使用 setWebViewClient 在 android webview 中的 html 页面上正确打开 google play 链接?

android - 如何将 FragmentFactory 与 FragmentStatePagerAdapter 一起使用