• TouTiao开源项目 分析笔记7 加载数据的过程


    1.以新闻页中的段子数据显示为例

    1.1.首先执行InitApp==>SplashActivity。

      因为在AndroidManifest.xml中定义了一个<intent-filter>中有定义启动页

    1.2.然后SplashActivity==>MainActivity。

      这是是intent的跳转。

    1.3.然后执行MainActivity中的onCreate==>执行里面的initView()

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            initView()

    1.4.然后执行onCreate中的showFragment函数。

       showFragment(savedInstanceState.getInt(POSITION))
       bottom_navigation!!.selectedItemId=savedInstanceState.getInt(SELECT_ITEM)

    1.5.然后进入NewsTabLayout中的getInstance函数

      newsTabLayout = NewsTabLayout.getInstance()
      ft.add(R.id.container, newsTabLayout, NewsTabLayout::class.java.name)

    1.6.然后执行getInstance函数==>new NewsTabLayout()

    public static NewsTabLayout getInstance(){
             if(instance==null){
                 instance=new NewsTabLayout();
             }
             return instance;
         }

    1.7.然后执行NewsTabLayout中的onCreateView(它是一个Fragment)  

    View view = inflater.inflate(R.layout.fragment_news_tab, container, false);
            initView(view);
            initData();
            return view;

    1.8.按顺序来==>initData()==>内部有一个initTabs()

       for(NewsChannelBean bean:channelList){
                 Fragment fragment=null;
                 String channelId=bean.getChannelId();
    
                 switch (channelId){
                     case "essay_joke":
                         if(map.containsKey(channelId)){
                             fragmentList.add(map.get(channelId));
                         }else{
                             fragment= JokeContentView.newInstance();
                             fragmentList.add(fragment);
                         }
                         break;

      这里就是加载了8个初始碎片。

    1.9.然后执行NewsTabLayout中的initData()中的

       adapter=new BasePagerAdapter(getChildFragmentManager(),fragmentList,titleList);
             viewPager.setAdapter(adapter);
             viewPager.setOffscreenPageLimit(15);

    1.10.进入RxBus==>注册了NewsTabLayout.TAG

     observable=RxBus.getInstance().register(NewsTabLayout.TAG);
             observable.subscribe(new Consumer<Boolean>() {
                 @Override
                 public void accept(Boolean isRefresh) throws Exception {
                     if(isRefresh){
                         initTabs();
                         adapter.recreateItems(fragmentList,titleList);
                     }
                 }
             });

    1.11.回到NewsTabLayout的onCreateView。返回view。

     @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 
                                @Nullable Bundle savedInstanceState) { View view
    = inflater.inflate(R.layout.fragment_news_tab, container, false); initView(view); initData(); return view; }

    1.12.然后执行Fragment的performCreateView()

    1.13.然后执行RxAppCompatActivity==>onStart()

    1.14.然后执行Activity==>convertToTranslucent()

    1.15.执行半天后到NewsTabLayout的onResume()中

     @Override
        public void onResume() {
            super.onResume();
            linearLayout.setBackgroundColor(SettingUtil.getInstance().getColor());
        }


    2.进入JokeContentView

    2.1.首先监听到的是setPresenter

     @Override
        public void setPresenter(IJokeContent.Presenter presenter) {
            if (null == presenter) {
                this.presenter = new JokeContentPresenter(this);
            }
        }

    2.2. 执行GroupBean==>自定义的一个Bean类非常庞大。

     private List<JokeContentBean.DataBean.GroupBean> groupList=new ArrayList<>();

    2.3.执行BaseFragment中的setPresenter函数

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

    2.4.然后进入LazyLoadFragment的onCreate()

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

    2.5.然后多次在JokeContentPresenter的构造函数中循环

    2.6.然后进入BaseFragment的onCreateView中

     @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 
                                @Nullable Bundle savedInstanceState) { View view
    = inflater.inflate(attachLayoutId(), container, false); initView(view); initData(); return view; }

    2.7.然后执行BaseListFragment的attachLayoutId函数。

    @Override
        protected int attachLayoutId() {
            return R.layout.fragment_list;
        }

    2.8.然后执行到JokeContentView的initView中

     @Override
        protected void initView(View view) {
            super.initView(view);
            adapter = new MultiTypeAdapter(oldItems);
            Register.registerJokeContentItem(adapter);
            recyclerView.setAdapter(adapter);
            recyclerView.addOnScrollListener(new OnLoadMoreListener() {
                @Override
                public void onLoadMore() {
                    if (canLoadMore) {
                        canLoadMore = false;
                        presenter.doLoadMoreData();
                    }
                }
            });
        }

    2.9.然后执行到Register中的registerJokeContentItem函数

     public static void registerJokeContentItem(@NonNull MultiTypeAdapter adapter) {
            adapter.register(JokeContentBean.DataBean.GroupBean.class, new JokeContentViewBinder());
            adapter.register(LoadingBean.class, new LoadingViewBinder());
            adapter.register(LoadingEndBean.class, new LoadingEndViewBinder());
        }

    2.10.然后执行JokeContentViewBinder

    2.11.然后回到JokeContentView的initView

      recyclerView.setAdapter(adapter);
            recyclerView.addOnScrollListener(new OnLoadMoreListener() {
                @Override
                public void onLoadMore() {
                    if (canLoadMore) {
                        canLoadMore = false;
                        presenter.doLoadMoreData();
                    }
                }
            });

    2.12.然后回到BaseFragment中的onCreateView函数

    @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View view = inflater.inflate(attachLayoutId(), container, false);
            initView(view);
            initData();   //=====执行到这里了
            return view;
        }

    2.13.然后进入JokeContentView中的initData()

     @Override
        protected void initData() {
    
        }

    2.14.然后回到LazyLoadFragment中,执行onActivityCreate

     @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            isViewInitiated = true;
            prepareFetchData();
        }

    2.15.执行prepareFetchData()

        public boolean prepareFetchData() {
            return prepareFetchData(false);
        }
    
        public boolean prepareFetchData(boolean forceUpdate) {
            if (isVisibleToUser && isViewInitiated && (!isDataInitiated || forceUpdate)) {
                fetchData();
                isDataInitiated = true;
                return true;
            }
            return false;
        }


    3.回到BaseFragment的onCreateView

    3.1.回到BaseFragment的onCreateView

     @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 
                                    @Nullable Bundle savedInstanceState) { View view
    = inflater.inflate(attachLayoutId(), container, false); initView(view); initData(); return view; }

    3.2.进入BaseListFragment中的attachLayoutId

    @Override
        protected int attachLayoutId() {
            return R.layout.fragment_list;
        }

    3.3.进入JokeContentView中的initView函数

     @Override
        protected void initView(View view) {
            super.initView(view);
            adapter = new MultiTypeAdapter(oldItems);
            Register.registerJokeContentItem(adapter);
            recyclerView.setAdapter(adapter);
            recyclerView.addOnScrollListener(new OnLoadMoreListener() {
                @Override
                public void onLoadMore() {
                    if (canLoadMore) {
                        canLoadMore = false;
                        presenter.doLoadMoreData();
                    }
                }
            });
        }

    3.4.再次进入Register

    public class Register {
        public static void registerJokeContentItem(@NonNull MultiTypeAdapter adapter) {
            adapter.register(JokeContentBean.DataBean.GroupBean.class, new JokeContentViewBinder());
            adapter.register(LoadingBean.class, new LoadingViewBinder());
            adapter.register(LoadingEndBean.class, new LoadingEndViewBinder());
        }
    }

    3.5.回到BaseFragment的onCreateView函数

      执行initData。

      进入JokeContentView

     @Override
        protected void initData() {
    
        }

    3.6.再次进入LazyLoadFragment的onActivityCreated

     @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            isViewInitiated = true;
            prepareFetchData();
        }

    3.7.回到BaseFragment的onCreateView 

     @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 
                                    @Nullable Bundle savedInstanceState) { View view
    = inflater.inflate(attachLayoutId(), container, false); initView(view); initData(); return view; }

    3.8.进入BaseListFragment的attachLayoutId

      @Override
        protected int attachLayoutId() {
            return R.layout.fragment_list;
        }


    4.总结一下

    4.1.首先加载底部导航栏的4个大碎片

      NewsTabLayout/PhotoTabLayout/VideoTabLayout/MediaChannelVideo

    4.2.加载NewsTabLayout详细的布局==>fragment_news_tab。

       然后确定8个默认的fragment(全部都是news_tab中的)

    4.3.NewsTabLayout在onCreateView中的initData初始化数据的时候,用上了RxBus+Observable

    4.4.执行LazyLoadFragment的setUserVisibleHint的不可见。

    4.5.继承关系的执行顺序为: 

    父类静态代码区和父类静态成员
    子类静态代码区和子类静态成员
    父类非静态代码区和普通成员
    父类构造函数
    子类非静态代码区和普通成员
    子类构造函数

    4.6.BaseFragment应该算是比较祖先级别的。所以先执行这个函数的onCreate==>onCreateView

      在BaseFragment中已经有了一个泛型的 presenter了。

    4.7.在子类中JokeContentView中有一个设置presenter的方法。设置成JokeContentPresenter。

      JokeContentPresenter实现了IJokeContent.Presenter接口。

      IJokeContent主要有两个内部接口View+Presenter。

    4.8.在JokeContentPresenter中进行API请求,主要函数为doLoadData()。

      采用了一个RetrofitFactory缓存机制。

      

    4.9.然后回到子类,也就是祖先的后代继承者。BaseListFragment

    4.10.然后到LazyLoadFragment中的onActivityCreate中执行 准备取数据的操作。prepareFetchData()。

    4.11.然后回到子类JokeContentView来加载数据了。onLoadData()

      首先执行BaseListFragment复写的onShowLoading函数。

      然后执行子类JokeContentPresenter来doLoadData()来请求数据。(调用方式为:presenter.doLoadData())

      这里进行了Cookie持久化操作。

    4.12.然后回到懒加载LazyLoadFragment中,成功执行了prepareFetchData,设置初始化为true。

    4.13.然后到祖先BaseFragment中的onCreateView函数中,加载fragment_list布局。

      执行祖先的initView==>成功转到JokeContentView的initView(Register注册了数据+recylerView监听滑动)

      然后转到BaseListFragment的initView(设置SwipeRefreshLayout的刷新事件)

      然后转到RetrofitFactory添加缓存

      然后转到JokeContentView的initView(继续Register+recyclerView监听滑动)

      这个Register里面关联了一个JokeContentViewBinder绑定,比较复杂。

      然后转到JokeContentPresenter的doLoadData来请求API

      然后到懒加载LazyLoadFragment的onActivityCreated中==>prepareFetchData()准备取数据

      然后回到祖先的onCreateView中加载fragment_list布局

      继续循环....


    既然选择了,便不顾风雨兼程。Just follow yourself.
  • 相关阅读:
    分享几个个人觉得挺漂亮的导航 Jquery
    C#程序打成 一键安装包InstallShield
    腾讯显IP的API
    C#综合揭秘——细说事务
    2012最新JQuery插件
    Flex各种用法及使用技巧一
    win7管理员账户的启用方法
    禁用win7休眠
    win7下移动文件夹
    win7下转移搜狗文件临时文件夹和IE临时文件夹的方法
  • 原文地址:https://www.cnblogs.com/Jason-Jan/p/7992838.html
Copyright © 2020-2023  润新知