• Android动态加载技术(插件化技术)


    No1:

    插件化技术的好处

    1)减轻应用的内存和CPU占用

    2)实现热插拔,即在不发布新版本的情况下更新某些模块

    No2:

    插件化方案必须要解决三个基础性问题:资源访问Activity生命周期的管理ClassLoader的管理

    No3:

    宿主是指普通的apk,插件一般指经过处理的dex或者apk。插件化框架大多采用apk作为插件,很多需要用到代理Activity,插件Activity的启动大多数是借助一个代理Activity来实现的。

    No4:

    Activity的工作主要是通过ContextImpl来完成的,Activity中有一个交mBase的成员变量,它的类型就是ContextImpl。Context中有两个抽象方法getAssetsgetResources,通过它们来获取资源的,真正实现在ContextImpl中。

    No5:

    资源访问

    加载apk中的资源

    protected void loadResources(){
        try{
            AssetManager assetManager = AssetManager.class.newInstance();
            Method addAssetPath = assetManager.getClass().getMethod("addAssetPath",String.class);
            addAssetPath.invoke(assetManager,mDexPath);
            mAssetManager = assetManager;
        }catch(Exception e){
            e.printStackTrace();
        }
        Resources superRes = super.getResources();
        mResources = new Resources(mAssetManager,superRes.getDisplayMetrics(),superRes.getConfiguration());
        mTheme = mResources.newTheme();
        mTheme.setTo(super.getTheme());
    }

    通过反射,调用AssetManager中addAssetPath方法,将一个apk中的资源加载到Resources对象中。然后通过AssetManager来创建一个新的Resources对象

    public final int addAssetPath(String path){
        synchronized(this){
            int res = addAssetPathNative(path);
            makeStringBlocks(mStringBlocks);
            return res;
        }
    }

    接着在代理Activity中实现getAssets和getResources

    @Override
    public AssetManager getAssets(){
        return mAssetManager == null?super.getAssets():mAssetManager;
    }
    
    @Override
    public Resources getResources(){
        return mResources == null?super.getResources():mResources;
    }

    No6:

    Activity生命周期的管理

    反射方式

    @Override
    protected void onResume(){
        super.onResume();
        Method onResume = mActivityLifecircleMethods.get("onResume");
        if(onResume!=null){
            try{
                onResume.invoke(mRemoteActivity,new Object[]{ })
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
    
    @Override
    protected void onPause(){
        Method onPause = mActivityLifecircleMethods.get("onPause");
        if(onPause!=null){
            try{
                onPause.invoke(mRemoteActivity,new Object[]{ })
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        super.onPause();
    }

    接口方式

    public interface DLPlugin{
        public void onStart();
        public void onRestart();
        public void onResume();
        public void onPause();
        public void onStop();
        public void onDestroy();
        ...
    }

    代理Actvitiy中调用

    ...
    @Override
    protected void onStart(){
        mRemoteActivity.onStart();
        super.onStart();
    }
    
    @Override
    protected void onRestart(){
        mRemoteActivity.onRestart();
        super.onRestart();
    }
    
    @Override
    protected void onResume(){
        mRemoteActivity.onResume();
        super.onResume();
    }

    mRemoteActivity就是DLPlugin的实现

    No7:

    插件ClassLoader的管理

    public class DLClassLoader extends DexClassLoader{
        private static final String TAG ="DLClassLoader";
        private static final HashMap<String,DLClassLoader> mPluginClassLoaders = new HashMap<String,DLClassLoader>();
        
        protected DLClassLoader(String dexPath,String optimizedDirectory,String libraryPath,Classloader parent){
            super(dexPath,optimizedDirectory,libraryPath,parent);
        }
        
        public static DLClassLoader getClassLoader(String dexPath,Context context,Classloader parentLoader){
            DLClassLoader dLassLoader = mPluginClassLoaders.get(dexPath);
            if(dLassLoader != null){
                return DLClassLoader;
            }
            
            File dexOutputDir = context.getDir("dex",Context.MODE_PRIVATE);
            final String dexOutputPath = dexOutputDir.getAbsolutePath();
            dLClassLoader = new DLClassLoader(dexPath,dexOutputPath,null,parentLoader);
            mPluginClassLoaders.put(dexPath,dLClassLoader);
            
            return dLClassLoader;
        }
    }

    通过将不同插件的ClassLoader存储在一个HashMap中,这样就可以保证不同插件中的类彼此互不干扰。

  • 相关阅读:
    sizeof运算符、虚函数、虚继承考点(待修改)
    sizeof运算符、字节对齐考点(面宝P50)
    浮点数的存储、类型转换知识点(面宝P34)
    赋值语句C++(面宝P29)
    求格子中的最短路径条数问题
    求两个数的最大公约数和最小公倍数Java(cvte考题)
    快速排序c代码
    希尔排序java代码
    快速排序java代码
    归并排序java代码
  • 原文地址:https://www.cnblogs.com/anni-qianqian/p/8340977.html
Copyright © 2020-2023  润新知