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布局
继续循环....