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布局
继续循环....
TouTiao开源项目 分析笔记7 加载数据的过程的更多相关文章
- TouTiao开源项目 分析笔记15 新闻详情之两种类型的实现
1.预览效果 1.1.首先看一下需要实现的效果. 第一种,文字类型新闻. 第二种,图片类型新闻. 1.2.在NewsArticleTextViewBinder中设置了点击事件 RxView.click ...
- TouTiao开源项目 分析笔记18 视频详情页面
1.效果预览 1.1.需要做到的真实效果 1.2.触发的点击事件 在MediaArticleVideoViewBinder的每一个item点击事件中: VideoContentActivity.lau ...
- TouTiao开源项目 分析笔记17 新闻媒体专栏
1.效果预览 1.1.要实现的效果 1.2.如何调转到新闻媒体专栏 点击右上角的用户图标. 在新闻详情页面的Fragment的菜单点击事件中触发. case R.id.action_open_medi ...
- TouTiao开源项目 分析笔记16 新闻评论
1.要达到的效果 1.1.主要效果图 点击了标题栏的消息图标后,然后会跳转到评论详情的页面. 1.2.触发的点击事件 在新闻详情的片段中的菜单点击事件中 设置上方标题栏的消息标的监听事件 case R ...
- TouTiao开源项目 分析笔记14 段子评论
1.段子页面详情 1.1.先看看预览界面吧 左边的页面已经实现了,现在的目的就是要实现点击左侧的每一个item 然后跳转到右边相应的段子详情页面. 1.2.首先肯定有右侧这个活动==>JokeC ...
- TouTiao开源项目 分析笔记20 问答详情
1.效果预览 1.1.效果预览,从问答列表开始 前面实现了从列表到内容. 这里主要讲解从内容到详情. 点击每一个回答内容,进入回答详情页面. 1.2.触发的点击事件 在WendaContentView ...
- TouTiao开源项目 分析笔记19 问答内容
1.真实页面预览 1.1.成果预览 首先是问答列表 然后每个item设置点击事件,进入问答内容列表 然后每一个问答内容也设置点击事件,进入问答详情 1.2.触发事件. 在WendaArticleOne ...
- TouTiao开源项目 分析笔记8 图解分析数据加载方式
1.整体构架 1.1.以一个段子页面为例,列出用到的主要的类,以图片的方式展示. 1.2.基础类 这里最基础的接口有: IBaseView<T>==>定义了5个方法. 然后最基础 ...
- TouTiao开源项目 分析笔记6
1.NewsChannelBean简单类笔记 1.1.Comparable接口的实现和使用 参考文章:Comparable接口的实现和使用. 因为NewsChannelBean实现了Comparabl ...
随机推荐
- 转:ACCESS数据库转ORACLE数据库分享
来源: 作者:zz 网上有很多文章介绍access转oracle数据库的方法,本人都尝试了,不是很成功,列举一下,后来人不必盲目试了,基本不成功: 1.Access-->excel-->P ...
- python类的反射
反射 通过字符串映射或者修改程序运行时的状态.属性.方法, 有一下4个方法 小例子--根据用户输入调用方法: class Dog(object): def __init__(self,name): s ...
- Struts2_用DomainModel接收参数
用域模型接收参数 User类 package com.bjsxt.struts2.user.model; public class User { private String name; privat ...
- pure-ftp 修改用户信息
1.修改用户test的密码 [root@localhost bin]# ./pure-pw passwd test #修改密码 Password: Enter it again: [root@loca ...
- C++ new new[]详解
精髓: operator new()完成的操作一般只是分配内存:而构造函数的调用(如果需要)是在new运算符中完成的. operator new和new 运算符是不同的,operator new只分配 ...
- 257. Binary Tree Paths (dfs recurive & stack)
Given a binary tree, return all root-to-leaf paths. Note: A leaf is a node with no children. Example ...
- C++学习之继承中的成员访问控制
由基类到派生类的过程中,在派生类里如何访问基类成员,以及派生类对象如何访问基类成员,是根据派生类在从基类派生时是以什么方式进行的派生:public.protect或者private.下面说一下在这三种 ...
- POJ-3614 Sunscreen---贪心+优先队列
题目链接: https://vjudge.net/problem/POJ-3614 题目大意: 有C个奶牛去晒太阳 (1 <=C <= 2500),每个奶牛各自能够忍受的阳光强度有一个最小 ...
- 起一个node服务
使用node开发一个应用,非常简单,甚至都不用去配置一堆文件来启动一个webu服务器,直接去官网把这一段示例代码拷过来 https://nodejs.org/en/about/ 中文网没有这个abou ...
- 1.1 NBU基本概念
1.1 NBU基本概念 1) Policy(备份策略) 备份策略定义一台或几台服务器的备份方法.它包括哪些服务器需要备份.备份哪些目录或文件.在什么时间备份.采用什么方式进行备份等.配置NBU主要指定 ...