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布局

  继续循环....

TouTiao开源项目 分析笔记7 加载数据的过程的更多相关文章

  1. TouTiao开源项目 分析笔记15 新闻详情之两种类型的实现

    1.预览效果 1.1.首先看一下需要实现的效果. 第一种,文字类型新闻. 第二种,图片类型新闻. 1.2.在NewsArticleTextViewBinder中设置了点击事件 RxView.click ...

  2. TouTiao开源项目 分析笔记18 视频详情页面

    1.效果预览 1.1.需要做到的真实效果 1.2.触发的点击事件 在MediaArticleVideoViewBinder的每一个item点击事件中: VideoContentActivity.lau ...

  3. TouTiao开源项目 分析笔记17 新闻媒体专栏

    1.效果预览 1.1.要实现的效果 1.2.如何调转到新闻媒体专栏 点击右上角的用户图标. 在新闻详情页面的Fragment的菜单点击事件中触发. case R.id.action_open_medi ...

  4. TouTiao开源项目 分析笔记16 新闻评论

    1.要达到的效果 1.1.主要效果图 点击了标题栏的消息图标后,然后会跳转到评论详情的页面. 1.2.触发的点击事件 在新闻详情的片段中的菜单点击事件中 设置上方标题栏的消息标的监听事件 case R ...

  5. TouTiao开源项目 分析笔记14 段子评论

    1.段子页面详情 1.1.先看看预览界面吧 左边的页面已经实现了,现在的目的就是要实现点击左侧的每一个item 然后跳转到右边相应的段子详情页面. 1.2.首先肯定有右侧这个活动==>JokeC ...

  6. TouTiao开源项目 分析笔记20 问答详情

    1.效果预览 1.1.效果预览,从问答列表开始 前面实现了从列表到内容. 这里主要讲解从内容到详情. 点击每一个回答内容,进入回答详情页面. 1.2.触发的点击事件 在WendaContentView ...

  7. TouTiao开源项目 分析笔记19 问答内容

    1.真实页面预览 1.1.成果预览 首先是问答列表 然后每个item设置点击事件,进入问答内容列表 然后每一个问答内容也设置点击事件,进入问答详情 1.2.触发事件. 在WendaArticleOne ...

  8. TouTiao开源项目 分析笔记8 图解分析数据加载方式

    1.整体构架 1.1.以一个段子页面为例,列出用到的主要的类,以图片的方式展示. 1.2.基础类 这里最基础的接口有:   IBaseView<T>==>定义了5个方法. 然后最基础 ...

  9. TouTiao开源项目 分析笔记6

    1.NewsChannelBean简单类笔记 1.1.Comparable接口的实现和使用 参考文章:Comparable接口的实现和使用. 因为NewsChannelBean实现了Comparabl ...

随机推荐

  1. sqlalchemy的cascades

    http://docs.sqlalchemy.org/en/latest/orm/cascades.html class Order(Base): __tablename__ = 'order' it ...

  2. 如何更换vim-airline的theme

    仓库位置: 点我直达 (主题以前是和airline在同个仓库的,现在独立出来了) 这些内置的这些主题,可以直接使用,方法是在 “.vimrc”文件中写 let g:airline_theme=&quo ...

  3. 如何处理Eclipse错误消息 The declared package does not match the expected package

    我从github下载了一个开源项目后,导入到自己Eclipse之后,遇到了这个烦人的错误消息: The declared package "com.sap.smartService" ...

  4. mysql主从分离

    1.工具: 两台机器 master:192.168.0.1 slave:192.168.0.2 2.master的配置 找到mysql的配置文件,一般centos的是/etc/my.cnf,ubunt ...

  5. httpclient开启代理,获取java中请求的url

    背景:在httpclent做post或者get请求时,请求返回的数据总是和预想的不一致,但是有不知道怎么排查问题,经同事说httpclient可以设置代理,就可以获取请求前数据的一些问题,帮助我排查问 ...

  6. POJ-1159 Palindrome---变成回文串的最小代价

    题目链接: https://cn.vjudge.net/problem/POJ-1159 题目大意: 题意很明确,给你一个字符串,可在任意位置添加字符,最少再添加几个字符,可以使这个字符串成为回文字符 ...

  7. 【洛谷4815】[CCO2014] 狼人游戏(树形DP)

    点此看题面 大致题意: 已知有平民和狼人共\(n\)个,每个平民会指控和保护任何人,每个狼人只会指控平民.保护狼人.告诉你\(m\)对指控与保护的关系,求有\(k\)个狼人的方案总数. 树形\(DP\ ...

  8. 初始化mysql数据库时提示字符编码错误的解决办法

    有时候在安装完数据库并初始化的时候会出现如下错误: root@localhost mysql-5.5.19]# bash scripts/mysql_install_db --user=mysql - ...

  9. python selenium 下拉框

    下拉框的处理如下代码: 定位select有很多种方式,这里介绍两种定位方式 1.二次定位 先定位到下拉框:self.dr.find_element_by_css_selector('#business ...

  10. kubernetes-控制器statefulset和Job(十三)

       从前面的学习我们知道使用Deployment创建的pod是无状态的,当挂载了Volume之后,如果该pod挂了,Replication Controller会再启动一个pod来保证可用性,但是由 ...