您的位置:首页 > 移动开发

appwidget

2011-11-19 23:38 155 查看
之前在公司项目中开发过图片widget,现在回故一下appwidget架构。

AppWidgetService:系统service之一,主要在后台负责所有appwidget的管理工作。Widget的添加,删除,更新等。

AppWidgetManager:Widgets管理类 

AppWidgetProvider
:继承自 BroadcastRecevier , 在AppWidget 应用 update、enable、disable 和 delete 时接收通知。其中,onUpdate、onReceive 是最常用到的方法,它们接收更新通知。 
AppWidgetProvderInfo:描述 AppWidget 的大小、更新频率和初始界面等信息,以XML 文件形式存在于应用的 res/xml/目录下。  
RemoteViews :一个可以在其他应用进程中运行的类,描述widget的视图

AppWidgetHost:提供了其他可以在自己UI嵌入widgets的应用程序和AppWidgetService的交互,如Home
screen

AppWidgetHostView:用来显示app widget的视图

AppWidgetPickActivity:显示widgets的列表

其实在我们实际开发中只需要实现AppWidgetProvider
,AppWidgetProvderInfo,RemoteViews ,就可以开发出自己的小插件。

另外我们知道android widget所支持的布局很有限:

FrameLayout


LinearLayout


RelativeLayout


AnalogClock


Button


Chronometer


ImageButton


ImageView


ProgressBar


TextView


ViewFlipper


ListView


GridView


StackView


AdapterViewFlipper

查看android源码,可以发现在AppWidgetHostView里面获取View时做了限制:

     // 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);

        }

    };

   protected View getDefaultView()
{

        if (LOGD) {

            Log.d(TAG, "getDefaultView");

        }

        View defaultView = null;

        Exception exception = null;

        

        try {

            if (mInfo != null) {

                Context theirContext = mContext.createPackageContext(

                        mInfo.provider.getPackageName(), Context.CONTEXT_RESTRICTED);

                mRemoteContext = theirContext;

                LayoutInflater inflater = (LayoutInflater)

                        theirContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

                inflater = inflater.cloneInContext(theirContext);

                inflater.setFilter(sInflaterFilter);

                defaultView = inflater.inflate(mInfo.initialLayout, this, false);

            } else {

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

            }

        } catch (PackageManager.NameNotFoundException e) {

            exception = e;

        } catch (RuntimeException e) {

            exception = e;

        }

        

        if (exception != null) {

            Log.w(TAG, "Error inflating AppWidget " + mInfo + ": " + exception.toString());

        }

        

        if (defaultView == null) {

            if (LOGD) Log.d(TAG, "getDefaultView couldn't find any view, so inflating error");

            defaultView = getErrorView();

        }

        

        return defaultView;

    }

要想支持复杂View,不但要考虑修改这里, 当然还要考虑一些触摸事件的派发,然widget的视图响应。

当然这样修改对支持添加widget的应用程序安全性是一个很大的威胁。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息