最近看了一下美团的开源的移动端页面模块化的开发框架Shield分析一下实现原理
关于Shield的框架的好处,介绍请看 https://tech.meituan.com/shield-opensource.html
git地址源码demo的下载
首先分析一下Demo中的DividerFragment,generaterDefaultConfigAgentList,在父类AgentManagerFragment中会被调用,主要的作用是new组件的配置信息类,加入到list中返回,下边看一下DividerAgentConfig这个组件的配置类public class DividerFragment extends AbsExampleFragment {
RecyclerView mRecyclerView;
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mRecyclerView = new RecyclerView(getContext());
return mRecyclerView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setAgentContainerView(mRecyclerView);
}
@Override
protected ArrayList generaterDefaultConfigAgentList() {
ArrayList configs = new ArrayList<>();
configs.add(new DividerAgentConfig());
return configs;
}
@Override
public String functionName() {
return "Divider";
}
}
实现了AgentListConfig接口,
getAgentInfoList()方法在后边的分析中会调用,现在看一下方法的实现,首先建立了一个三维数组,然后调用AgentInfohelper.getAgents()把三维数组转成Map
public class DividerAgentConfig implements AgentListConfig {
private static final String AGENT_PKG_NAME = "com.example.shield.divider.agent.";
@Override
public boolean shouldShow() {
return true;
}
@Override
public Map getAgentInfoList() {
String[][][] agentArray = {
{
{"default_divider", AGENT_PKG_NAME + "TestDividerAgent"},
}
};
return AgentInfoHelper.getAgents(agentArray);
}
@Override
public Map> getAgentList() {
return null;
}
}
看一下DividerFragment的父类AgentManagerFragment,实现了AgentCellBridgeInterface,DriverInterface,ShieldConainer
Interface,在onActivityCreated中通过getAgentManager获取CommonAgentManager(继承了LightAgentManager)对象,
j接下来调用CommonAgentManager的setupAgent,看一下setupAgent的参数,genneraterDefaultConfigList()就是上边DividerFragment实现的,在CommonAgentManager没有对setupAgent进行实现,我们看一下他的父类LightAgentManager的实现的方法
AgentManagerFragment:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
cellManager = getCellManager();
if (cellManager instanceof SectionRecyclerCellManager) {
((SectionRecyclerCellManager) cellManager).setWhiteBoard(whiteBoard);
}
agentManager = getAgentManager();
agentManager.setupAgents(savedInstanceState, generaterDefaultConfigAgentList());
if (pageContainer != null) {
pageContainer.onActivityCreated(savedInstanceState);
setAgentContainerView(pageContainer.getAgentContainerView());
}
}
组件是如何进行渲染的呢,然后继续分析setupAgents,遍历agentList,获取组件对象,调用组件的onCreate声明周期,然后继续调用agentCellBridgeInterface的updateCells对象,传入刚刚初始化的组件list,agentCellBridgeInterface是LightAgentmanager在构造函数传入的对象,所以回到AgentManagerFragment,的updateCell
LightAgentManager:
@Override
public void setupAgents(Bundle savedInstanceState, ArrayList defaultConfig) { //第二个参数是组件的信息
setupAgents(defaultConfig);
ArrayList addList = new ArrayList();
for (String name : agentList) {
AgentInterface agent = agents.get(name); //根据key获取组件
if (agent != null) {
Bundle b = savedInstanceState == null ? null : savedInstanceState.getBundle("agent/"
+ name);
agent.onCreate(b); //回调组件的onCreate
addList.add(agent);
}
}
agentCellBridgeInterface.updateCells(addList, null, null);
dispatchCellChanged(fragment.getActivity(), null, null);
}
protected void setDefaultAgent(ArrayList defaultConfig, String keyPath, String index) {
Map defaultAgent = getDefaultAgentList(defaultConfig); //对组件进行初始化
if (defaultAgent == null) {
// throw new RuntimeException("generaterDefaultAgent() can not return null");
Log.e("Shield", "generaterDefaultAgent() can not return null");
return;
}
try {
for (Map.Entry entry : defaultAgent.entrySet()) { //遍历组件info的map
String key;
if (!"".equals(keyPath)) {
key = keyPath + AGENT_SEPARATE + entry.getKey();
} else {
key = entry.getKey();
}
if (!agents.containsKey(key)) {
agentList.add(key);
AgentInterface cellAgent = constructAgents(entry.getValue().agentClass); //反射构造类的实例
if (cellAgent != null) {
String childIndex;
if (!"".equals(keyPath)) {
childIndex = index + "." + entry.getValue().index;
} else {
childIndex = entry.getValue().index;
}
cellAgent.setIndex(childIndex);
cellAgent.setHostName(key);
agents.put(key, cellAgent);
if (cellAgent instanceof ShieldContainerInterface) {
setDefaultAgent(((ShieldContainerInterface) cellAgent).generaterConfigs(), key, childIndex);
}
}
}
}
} catch (Exception e) {
// Log.e(TAG, e.toString());
}
}
protected Map getDefaultAgentList(ArrayList defaultConfig) {
if (defaultConfig == null) {
Log.e("Shield", "generaterDefaultConfigAgentList return null");
// throw new RuntimeException("generaterDefaultConfigAgentList return null");
return null;
}
for (AgentListConfig agentListConfig : defaultConfig) { //遍历配置的组件信息
try {
if (agentListConfig.shouldShow()) {
Map result = agentListConfig.getAgentInfoList(); //获取封装好的组件的key AgentInfo
if (result == null) {
result = new LinkedHashMap();
Map> tmp = agentListConfig.getAgentList(); //null
for (Map.Entry> entry : tmp.entrySet()) {
result.put(entry.getKey(), new AgentInfo(entry.getValue(), ""));
}
}
return result;
}
} catch (Exception e) {
// if (Environment.isDebug()) {
// throw new RuntimeException("there has a exception " + e);
// }
e.printStackTrace();
return null;
}
}
// throw new RuntimeException("getDefaultAgentList() agentListConfig no one should be shown?");
Log.e("Shield", "getDefaultAgentList() agentListConfig no one should be shown?");
return null;
}
@Override
public void updateCells(ArrayList addList, ArrayList updateList, ArrayList deleteList) {
cellManager.updateCells(addList, updateList, deleteList);
}
看一下SectionRecyclerCellManager的updateCells,首先遍历模块组件的对象,然后根据组件对象的信息,创建SectionPieceAdapter(继承RecyclerView.Adapter),把模块组件,模块组件信息,刚刚创建的适配器封装成Cell,加入hashMap对象cells,然后遍历需要更新删除的组件集合,对cells进行更改,最后一行比较是重点
@Override
public void updateCells(ArrayList addList, ArrayList updateList, ArrayList deleteList) {
//添加新的
if (addList != null && !addList.isEmpty()) {
for (AgentInterface addAgent : addList) {
if (addAgent.getSectionCellInterface() != null) {
RecyclerView.Adapter adapter = createRecyclerViewAdapter(addAgent); //创建RecyclerView的适配器
Cell c = new Cell(); //封装成Cell
c.owner = addAgent;
c.name = addAgent.getAgentCellName();
c.recyclerViewAdapter = adapter;
cells.put(getCellName(addAgent), c); //cell放在集合cells中
}
}
}
//更新原来有的位置
//只更新之前存在的Agent的Cell的index
//因为是viewgroup会有多个cell,需要把agent对应的多个cell的index都更新,之后统一notify
if (updateList != null && !updateList.isEmpty()) { //需要更新的cell
HashMap copyOfCells = (HashMap) cells.clone();
for (AgentInterface updateCell : updateList) {
if (updateCell.getSectionCellInterface() != null) {
for (Map.Entry entry : copyOfCells.entrySet()) {
//判断owner属于该agent,并且之前的name是和目前cellNam+内部顺序一致(找到对应的Cell)
if (entry.getValue().owner == updateCell) {
//替换cell的index
Cell temp = entry.getValue();
cells.remove(entry.getKey());
cells.put(getCellName(updateCell), temp);
}
}
}
}
}
//删除需要删除的
if (deleteList != null && !deleteList.isEmpty()) { //需要删除的cell
for (AgentInterface deleteCell : deleteList) {
Iterator> itr = cells.entrySet().iterator();
while (itr.hasNext()) {
Cell c = itr.next().getValue();
if (c.owner == deleteCell) {
itr.remove();
}
}
}
}
notifyCellChanged(); //更新cell
}
public void updateAgentContainer() {
sort = new ArrayList(cells.values()); //获取cells的value
Collections.sort(sort, cellComparator); //对sort进行排序
resetAgentContainerView(); //重新设置
//根据多维index(xx.xx.xx.xx)还原实际的二维结构分组。
cellGroup = new ArrayList<>();
ArrayList cellArrayList = new ArrayList<>();
CellGroupIndex currentCellGroup = null;
for (Cell cell : sort) { //对sort进行遍历 进行分组
String indexStr = cell.owner.getIndex(); //获取index
CellGroupIndex cellGroupIndex = createCellGroup(indexStr); //创建cellGroup
if (currentCellGroup == null) {
cellArrayList = new ArrayList<>();
cellArrayList.add(cell);
} else {
boolean isSameGroup = isSameGroup(currentCellGroup, cellGroupIndex);
if (isSameGroup) {
cellArrayList.add(cell);
} else {
cellGroup.add(cellArrayList);
cellArrayList = new ArrayList<>();
cellArrayList.add(cell);
}
}
currentCellGroup = cellGroupIndex;
}
if (cellArrayList != null && (!cellArrayList.isEmpty())) {
cellGroup.add(cellArrayList);
}
//根据实际的二维结构数组重排index
if (cellGroup != null) {
for (int i = 0; i < cellGroup.size(); i++) {
if (cellGroup.get(i) == null) continue;
for (int j = 0; j < cellGroup.get(i).size(); j++) {
if (cellGroup.get(i).get(j) == null) continue;
try {
Cell cell = cellGroup.get(i).get(j); //遍历获取cell
cell.groupIndex = AgentInfoHelper.addZeroPrefix(i, AgentInfoHelper.getIntStrLength(cellGroup.size()));
cell.innerIndex = AgentInfoHelper.addZeroPrefix(j, AgentInfoHelper.getIntStrLength(cellGroup.get(i).size()));
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
}
}
if (!sort.isEmpty()) {
for (int i = 0; i < sort.size(); i++) {
Cell c = sort.get(i);
if (c.recyclerViewAdapter == null)
continue;
FinalPieceAdapter finalPieceAdapter;
if (c.recyclerViewAdapter instanceof FinalPieceAdapter) {
finalPieceAdapter = (FinalPieceAdapter) c.recyclerViewAdapter;
} else {
finalPieceAdapter = new FinalPieceAdapter(mContext, (PieceAdapter) c.recyclerViewAdapter, groupManager); //cell的adapter封装一下
}
groupManager.addAdapter(finalPieceAdapter, i, c.groupIndex); //封装adapter
c.recyclerViewAdapter = finalPieceAdapter; //封装好的adapter赋值给cell
if (whiteBoard != null) {
if (finalPieceAdapter.getTotalItemCount() > 0) {
whiteBoard.putBoolean(ShieldConst.AGENT_VISIBILITY_KEY + c.owner.getHostName(), true);
} else {
whiteBoard.putBoolean(ShieldConst.AGENT_VISIBILITY_KEY + c.owner.getHostName(), false);
}
}
addCellToContainerView(c);
}
}
mergeRecyclerAdapter.notifyDataSetChanged();
} | |
到这里,我们完成了组件模块的初始化,根据组件模块创建适配器,适配器的整合(后边进行具体分析)那么适配器是如何关联到recyclerView上的呢,我们看一下DividerFragment,onActivityFragment,调用setAgentContainerView,最后调用SectionRecyclerCellManager的setAgentContainerView
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setAgentContainerView(mRecyclerView);
}
@Override
public void setAgentContainerView(RecyclerView containerView) { //给recyclerView设置adapter
if (containerView == null) {
return;
}
this.recyclerView = containerView;
if (recyclerView.getLayoutManager() == null) {
layoutManager = new LinearLayoutManagerWithSmoothOffset(mContext);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
} else if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
}
recyclerView.setAdapter(mergeRecyclerAdapter);
if (mCanExposeScreen) {
recyclerView.removeOnScrollListener(mOnScrollListener);
recyclerView.addOnScrollListener(mOnScrollListener);
}
}
现在关于组建的渲染工作完成
对于多个组建的适配器如何整合继续分析
SectionRecyclerManager的addCellToContainerView调用了MergeSectionDividerAdapter的addAdapter,把Cell的适配器添加到MergeSectionDividerAdapter pieces集合,getItemViewType的参数分别代表了第几个section,section的第几行,根据参数查找对应的SectionPosition的信息,从pieces中回去adapter,返回type类型,在onCreateViewHolder,根据viewType获取对应的adapter,然后调用adapter的onCreateViewHolder,到这里基本的逻辑分析完了,只是个人的见解,希望有更好的分析,我可以参考学习
public void addAdapter(PieceAdapter adapter) {
adapter.registerAdapterDataObserver(mObserver);
pieces.add(adapter);
updateInfo();
notifyDataSetChanged();
}
@Override
public int getItemViewType(int sectionIndex, int position) { //根据传递过来的sectionIndex,position获取type
DetailSectionPositionInfo info = getDetailSectionPositionInfo(sectionIndex, position); //获取section的position
if (info != null) {
PieceAdapter adapter =
pieces.get(info.adapterIndex); //获取adapter的信息
if (adapter != null) {
int type = adapter.getItemViewType(info.adapterSectionIndex, info.adapterSectionPosition); //获取type
Pair pair = new Pair<>(adapter.getMappingKey(), type);
if (typeMap.containsKey(pair)) {
return typeMap.get(pair);
}
}
}
return 0;
}
@Override
public BasicHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Pair pair = getAdapterType(viewType);
if (pair != null && !TextUtils.isEmpty(pair.first)) {
PieceAdapter adapter = getAdapterByMappingKey(pair.first);
if (adapter != null) {
if (performanceManager != null) {
Date start = new Date();
BasicHolder holder = adapter.onCreateViewHolder(parent, pair.second);
Date end = new Date();
performanceManager.insertRecord(pageName, adapter, "onCreateView", start.getTime(), end.getTime());
return holder;
} else {
return adapter.onCreateViewHolder(parent, pair.second);
}
}
}
return null;
}