Android动态加载第三方APK的View研究过程

热加载第三方应用的View,实现动态修改宿主应用

背景:

我们要做一个Launcher,Launcher上面要显示apk的界面,但是的话,如果使用widget的方式没法进行复杂的交互,所以要想办法把第三方的apk里的View,动态地加载进来。

怎么实现呢?

Android原生的Launcher其实也是个框架,去遍历孩子,然后显示出来。这里也一样,定好相关的接口,然后各自己的应用需要去实现,再根据条件去遍历/system/app下的应用,然后加载相关的View出来。当对应的View绑定到窗口以后,就去绑定对应的服务,由服务来对这个View进行数据交互。这样子的互动,会比较好一点。

如果说是音乐这些还比较简单,要是地图的控制就比较复杂了。用Widget实现不了。如果能用绘制的View那就么是比较好实现的。

开始啦

这里是Demo,也就是前期的技术预言,所以不需要做一个完整的项目。
要点:能够加载到第三方apk里面的View,并且显示出来,同时可以操作,进行数据交互。
- 有宿主,和第三方APK
- 第三方apk已经安装,所在目录是/system/app/
- 能够进行数据交互,除了简单的点击以外,还可以进行复杂的操作。

还是先看效果吧:

就是实现上效果,可是,这个项目只有一个类,那就是MainActivity.

而且可以进行操作哦,可以点击下一首,上一首,播放!

那是怎么做到的呢?

实现过程

创建一个宿主项目,对应的也是我们以后的Launcer,我们暂且起名为PretendLauncherDemo

我们加载一个界面需要上下文吧,所以就有了:

        //获取TestB的Context
        private Context getRemoteContext(String packageName) throws PackageManager.NameNotFoundException {
        return createPackageContext(packageName,Context.CONTEXT_IGNORE_SECURITY |   Context.CONTEXT_INCLUDE_CODE);
            }

这个方法就是通过包名获取到对应app的上下文对象。

但是要注意的时,通过这个上下文获取到的ApplicationContext是空的呢?也就是说,部分的图片加载工具,比如说ImageLoader,比如说毕加索这些可能拿不到图片,直接崩溃掉,因为context.getApplicationContext拿不到,返回的内容为null。

有了上下文以后,做什么事情都好说,如果只是获取资源文件,这是非常简单的事情:


            /**
            * 获取资源对应的编号
            *
            * @param res
            * @param resName
            * @param resType layout、drawable、string
            * @return
            */
            private int getId(Resources res, String resType, String resName, String packageName) {
            return res.getIdentifier(resName, resType, packageName);
            }

有了id,你啥不能拿到呢对吧!
获取View

    /**
     * 获取View
     *
     * @param context
     * @param resId
     * @return
     */
    public View getView(Context context, int resId) {
        return ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(resId, null);
    }

获取颜色值:

     /**
     * 获取颜色
     *
     * @param context
     * @param colorId
     * @return 颜色值
     */
    public int getColor(Context context, int colorId) {
        return context.getResources().getColor(colorId);
    }

其他的获取方式都是一样的。

给大家一个思路:如果遇到问题,就一个一个地去解决即可!哈哈哈!!!!

欢迎关注微信公众号

你可能感兴趣的:(android)