http://p.codekk.com/detail/Android/GeekGhost/Ghost
最近在学习这个开源的App的源码,整体项目是可以正常运行的,整个项目采用的是MVP设计模式,其中App打开时的欢迎界面有一段运行逻辑实在搞不明白,特请教各位大神。具体代码如下:WelcomeActivitypackage com.zcy.ghost.vivideo.ui.activitys;import android.os.Bundle;import com.zcy.ghost.vivideo.R;
import com.zcy.ghost.vivideo.base.BaseActivity;
import com.zcy.ghost.vivideo.presenter.WelcomePresenter;
import com.zcy.ghost.vivideo.ui.view.WelcomeView;import butterknife.BindView;
import butterknife.ButterKnife;public class WelcomeActivity extends BaseActivity {    @BindView(R.id.welcome_view)
    WelcomeView welcomeView;    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_welcome);
        unbinder = ButterKnife.bind(this);
        mPresenter = new WelcomePresenter(welcomeView);
    }
}这个是App刚打开时的欢迎界面,逻辑比较简单WelcomePresenterpackage com.zcy.ghost.vivideo.presenter;import android.support.annotation.NonNull;import com.zcy.ghost.vivideo.base.RxPresenter;
import com.zcy.ghost.vivideo.presenter.contract.WelcomeContract;
import com.zcy.ghost.vivideo.utils.RxUtil;
import com.zcy.ghost.vivideo.utils.StringUtils;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;import rx.Observable;
import rx.Subscription;
import rx.functions.Action1;/**
 * Description: WelcomePresenter
 * Creator: yxc
 * date: 2016/9/22 13:17
 */
public class WelcomePresenter extends RxPresenter implements WelcomeContract.Presenter {
    WelcomeContract.View mView;
    private static final int COUNT_DOWN_TIME = 2200;    public WelcomePresenter(@NonNull WelcomeContract.View oneView) {
        mView = StringUtils.checkNotNull(oneView);
        mView.setPresenter(this);
        getWelcomeData();
    }    @Override
    public void getWelcomeData() {
//        Subscription rxSubscription = RetrofitHelper.getVideoApi().getHomePage()
//                .compose(RxUtil.<VideoHttpResponse<VideoRes>>rxSchedulerHelper())
//                .compose(RxUtil.<VideoRes>handleResult())
//                .subscribe(new Action1<VideoRes>() {
//                    @Override
//                    public void call(final VideoRes res) {
//                        if (res != null) {
//                            if (mView.isActive()) {
//                                mView.showContent(res);
//                            }
//                        }
//                        startCountDown();
//                    }
//                }, new Action1<Throwable>() {
//                    @Override
//                    public void call(Throwable throwable) {
//                        startCountDown();
//                    }
//                });
//        addSubscrebe(rxSubscription);
        mView.showContent(getImgData());
        startCountDown();
    }    private void startCountDown() {
        Subscription rxSubscription = Observable.timer(COUNT_DOWN_TIME, TimeUnit.MILLISECONDS)
                .compose(RxUtil.<Long>rxSchedulerHelper())
                .subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long aLong) {
                        mView.jumpToMain();
                    }
                });
        addSubscrebe(rxSubscription);
    }    private List<String> getImgData() {
        List<String> imgs = new ArrayList<>();
        imgs.add("file:///android_asset/a.jpg");
        imgs.add("file:///android_asset/b.jpg");
        imgs.add("file:///android_asset/c.jpg");
//        imgs.add("file:///android_asset/d.jpg");
        imgs.add("file:///android_asset/e.jpg");        imgs.add("file:///android_asset/f.jpg");
        imgs.add("file:///android_asset/g.jpg");
        return imgs;
    }}这个是欢迎界面的presenter,注意里面的mView.showContent(getImgData())这行代码WelcomeViewpackage com.zcy.ghost.vivideo.ui.view;import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;import com.google.common.base.Preconditions;
import com.zcy.ghost.vivideo.R;
import com.zcy.ghost.vivideo.base.RootView;
import com.zcy.ghost.vivideo.component.ImageLoader;
import com.zcy.ghost.vivideo.presenter.contract.WelcomeContract;
import com.zcy.ghost.vivideo.ui.activitys.WelcomeActivity;
import com.zcy.ghost.vivideo.utils.EventUtil;
import com.zcy.ghost.vivideo.utils.JumpUtil;
import com.zcy.ghost.vivideo.utils.StringUtils;import java.util.List;import butterknife.BindView;
import butterknife.ButterKnife;
/**
 * Description: WelcomeView
 * Creator: yxc
 * date: 2016/9/22 13:20
 */
public class WelcomeView extends RootView implements WelcomeContract.View {    private WelcomeContract.Presenter mPresenter;    @BindView(R.id.iv_welcome_bg)
    ImageView ivWelcomeBg;    public WelcomeView(Context context) {
        super(context);
        init();
    }
    public WelcomeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }    private void init() {
        mContext = getContext();
        inflate(mContext, R.layout.activity_welcome_view, this);
        unbinder = ButterKnife.bind(this);
        mActive = true;
    }    @Override
    public void setPresenter(WelcomeContract.Presenter presenter) {
        mPresenter = Preconditions.checkNotNull(presenter);
    }    @Override
    public void showError(String msg) {
        EventUtil.showToast(mContext, msg);
    }    @Override
    public boolean isActive() {
        return mActive;
    }    @Override
    public void showContent(List<String> list) {
        if (list != null) {
            int page = StringUtils.getRandomNumber(0, list.size() - 1);
            ImageLoader.load(mContext, list.get(page), ivWelcomeBg);
            ivWelcomeBg.animate().scaleX(1.12f).scaleY(1.12f).setDuration(2000).setStartDelay(100).start();
        }    }    @Override
    public void jumpToMain() {
        JumpUtil.go2MainActivity(mContext);
        ((WelcomeActivity) mContext).overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
    }
}这个是欢迎界面的View,注意里面的showContent方法接口的代码WelcomeContractpackage com.zcy.ghost.vivideo.presenter.contract;
import com.zcy.ghost.vivideo.base.BasePresenter;
import com.zcy.ghost.vivideo.base.BaseView;import java.util.List;/**
 * Description: WelcomeContract
 * Creator: yxc
 * date: 2016/9/22 13:16
 */
public interface WelcomeContract {    interface View extends BaseView<Presenter> {        boolean isActive();        void showContent(List<String> list);        void jumpToMain();
    }    interface Presenter extends BasePresenter {
        void getWelcomeData();
    }
}问题如下:
presenter里面调用的mView.showContent(getImgData()),里面mView是接口的实例,接口里面的showContent方法是空方法,但是从App运行的样子来看,这里调用的方法应该是View里面的showContent方法,请问这个是怎么实现的?逻辑是什么?
在此先谢谢各位大神的关注和讲解!!

解决方案 »

  1.   

    通过看代码逻辑应该很好理解呀,就是通过定义些接口也就是所谓的行为来告诉你我有这些功能,让具体的实例去实现。还有你所说的空方法在哪,我看代码中有实现这个接口呀@Override
        public void showContent(List<String> list) {
            if (list != null) {
                int page = StringUtils.getRandomNumber(0, list.size() - 1);
                ImageLoader.load(mContext, list.get(page), ivWelcomeBg);
                ivWelcomeBg.animate().scaleX(1.12f).scaleY(1.12f).setDuration(2000).setStartDelay(100).start();
            }    }
      

  2.   

    首先要理解MVP模式,该项目用的是MVP模式, Presenter负责业务逻辑,WelcomeActivity的逻辑就是加载图片,并显示。由 WelcomePresenter的如下方法完成
        @Override
        public void getWelcomeData() {
            mView.showContent(getImgData());
            startCountDown();
        }
    为什么要调mView.showContent()? View负责显示内容。 你可以看到WelcomeActivity的定义 实现了 WelcomeContract.View里的接口showContent() ,
    public class WelcomeActivity extends BaseMvpActivity<WelcomePresenter> implements WelcomeContract.View {
         ....
         @Override
        public void showContent(List<String> list) {
            if (list != null) {
                int page = StringUtils.getRandomNumber(0, list.size() - 1);
                ImageLoader.load(mContext, list.get(page), ivWelcomeBg);
                ivWelcomeBg.animate().scaleX(1.12f).scaleY(1.12f).setDuration(2000).setStartDelay(100).start();
            }
        }
    }
    就这么简单哈
      

  3.   

    这个你要看下多态的概念,    public WelcomePresenter(@NonNull WelcomeContract.View oneView) {
            mView = StringUtils.checkNotNull(oneView);
            mView.setPresenter(this);
            getWelcomeData();
        }
    这里是有赋值的,指向一个具体对象,而不是接口
      

  4.   

    mView就是WelcomeView,是通过activity里onCreate的这句mPresenter = new WelcomePresenter(welcomeView);传过去的
    WelcomeView实现了WelcomeContract.View,在presenter中调用这句 mView.showContent(getImgData())就是调用了WelcomeView的showContent方法。这个做法类似接口回调