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所支持的布局很有限:
查看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的应用程序安全性是一个很大的威胁。
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的应用程序安全性是一个很大的威胁。
相关文章推荐
- Android 第三方桌面,怎么请求Widget的android.permission.BIND_APPWIDGET
- android添加默认appwidget
- Android App Widget的简单使用
- [Android笔记] 关于 AppWidget 动态更新:RemoteViews 更新缓慢&内存溢出
- Android-接受来自Appwidget的广播、更新Appwidget控件的状态
- Android AppWidget系统框架
- Android-AppWidget
- 关于在ArcGIS WebAppBuilder的widget开发中引入EasyUI的一些方法
- Android Launcher开发(二)AppWidget(桌面小部件)解析
- Android AppWidget核心之AppWidgetService
- (4.1.27.1)Android之桌面组件App Widget案例之高仿墨迹天气桌面组件
- Android 桌面组件【app widget】 进阶项目--心情记录器
- AppWidget的入门讲解
- Android笔记之AppWidget
- Android---快速拨话程序(涵盖appWidget、Tab、联系人、多线程、自定义ListView使用)
- android中的appwidget理解巩固
- Android App Widget中如何调用RemoteView中的函数
- Android开发视频第二季之七:App Widget(3)
- Android中AppWidget的分析与应用:AppWidgetProvider
- Android AppWidget实例验证