从源码解析,为何AppWidget不支持自定义View

本文深入探讨为何Android的AppWidget不支持自定义View。从AppWidgetHostView的代码解析,揭示了问题的关键在于加载类的过程中,AppWidget使用BootClassLoader,无法加载特定应用APK中的自定义View类,而自定义View需要在运行时由对应的ClassLoader加载。只有在类头添加@RemoteViews.RemoteView注解并在framework层面有修改权限时,才能在AppWidget中使用自定义View。

为何AppWidget不支持自定义View

几个大类RemoveViews, RemoveViewsService, RemoveViewsFactory就不说了。不是本节主题。

 

切入正题,直接从AppWidgetHostView.java开始讲。这就相当于ActivityDecorView

贴一段代码先,来自AppWidgetHostView.java版本:5.1

    /**

     * Inflate and return the default layout requested by AppWidget provider.

     */

    protected View getDefaultView() {

        ......

 

        try {

            if (mInfo != null) {

                Context theirContext = getRemoteContext();

                mRemoteContext= theirContext;

                LayoutInflater inflater = (LayoutInflater)

                        theirContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

                inflater = inflater.cloneInContext(theirContext);

                inflater.setFilter(sInflaterFilter);

                AppWidgetManager manager = AppWidgetManager.getInstance(mContext);

                Bundle options = manager.getAppWidgetOptions(mAppWidgetId);

 

                int layoutId = mInfo.initialLayout;

                ......

                defaultView = inflater.inflate(layoutId, this, false);

            } else {

                Log.w(TAG, "can't inflate defaultView because mInfo is missing");

            }

        } catch (RuntimeException e) {

            exception = e;

        }

 

        ......

 

        return defaultView;

}


再看下面这段代码sInflaterFilter的定义

    // When we're inflating the initialLayout for a AppWidget, we only allow

    // views that are allowed in RemoteViews.

    static final LayoutInflater.Filter sInflaterFilter = new LayoutInflater.Filter() {

        public boolean onLoadClass(Class clazz) {

            return clazz.isAnnotationPresent(RemoteViews.RemoteView.class);

        }

    };

再贴一段getRemoteContext()的实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值