美团shield UI框架源码分析

最近看了一下美团的开源的移动端页面模块化的开发框架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调用了重载方法,最后调用setDefaulAgent,在第一行中调用getDefaultAgentList(调用DividerAgentConfig的getAgentInfoList,在前面已经分析)获取Map对象,然后进行对Map遍历,调用constructAgents反射构造组件对象,然后拼接index,key设置成组件的属性,复合组件递归调用setupAgent进行初始化,组件的key保存在agentlist,组件保存在agents这个Map对象,到这里,根据组件的配置的信息,对组件的初始完成

组件是如何进行渲染的呢,然后继续分析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;
    }


updateCell,调用了cellManagerde updateCells,cellManager是SectionRecyclerCellManager对象
 @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
    }

最后调用updateAgentContainer,对cell进行分组,保存在二维结构cellGroup,重新排列index,继续遍历cell集合,cell模块组件保存的适配器封装成FinalPieceAdapter(类似于代理模式,通过FinalPieceAdapter调用SectionPieceAdapter),调用addCellToContainerView()方法,把cell模块组件的适配器封装到MergeSectionDividerAdapter内(把适配器进行整合具体代码后边进行分析),最后更新适配器
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;
    }
















你可能感兴趣的:(android)