RemoteViews概述


1.RemoteView概述 html

到目前为止,我发现RemoteView会用在两个地方:一个是在AppWidget,另一个是在Notification

先从官方对他的定义来看: 
RemoteView-- 
A class that describes a view hierarchy that can be displayed in another process. The hierarchy is inflated from a layout resource file, and this class provides some basic operations for modifying the content of the inflated hierarchy. 

RemoteView描述一个view,而这个view是在另一个进程显示的。它inflate于layout资源文件。而且提供了能够修改过view内容的一些简单基础的操做。 

从这个定义咱们就知道RemoteView是用来描述一个垮进程显示的view。从而你就会明白为何AppWidget和Nofication须要用到它了。 
1,AppWidget---RemoteView 
咱们都知道AppWidgetProvider是一个BrocaseReceiver,只是接受到Enable, Update,disale,delete这些message,而真正显示界面的是AppWidgetHostView(这是在Launcher里面实现的)这中间就是经过RemoteView来沟通。经过RemoteView告诉Launcher你想要的AppWidget是长什么样。 

2,Notification--RemoteView 
若你想自定义你的Notification也必须经过RemoteView.由于你定义的Nofication和显示Notification也是两个不一样的进程。 

在android 2.2以前,RemoteView只支持一些简单的view:TextView, Framelaout..不支持ListView和GridView等复杂的view,它的操做也是简单的click。在网上有人说是经过@RemoteView这个标签肯定RemoteView是否支持view.在view的源文件加上@RemoteView这个标签就能够支持了。这个我尚未去试试过。 (在htc sence ui 中咱们能够看到有用到listview,gridview,这是怎么作到的呢,看下面说明)

在android 3.0,Google增强这方面,下面来源官方文档: 
Expanded Home screen widgets 
Home screen widgets are popular with users because they offer fast access to application-specific data directly from the home screen. Android 3.0 lets developers take home screen widgets to the next level, offering more types of content and new modes of interaction with users. Developers can now use more standard UI widget types home screen widgets, including widgets that let users flip through collections of content as 3D stacks, grids, or lists. Users can interact with the home screen widgets in new ways, such as by using touch gestures to scroll and flip the content displayed in a widget.  java

2.Android AppWidget 如何支持复杂的View  android

整理自:http://407827531.iteye.com/blog/605736 app

一直想知道如何在AppWidget里面添加 ListView,EditText 这些复杂的View.咱们知道要在AppWidget里添加 View都是经过RemoteView来作到了,然而RemoteView自己功能很弱,支持的操做不多,并且支持RemoteView的Widget不多: 
在Dev Guide中有下面这段:  ide

说明
A RemoteViews object (and, consequently, an App Widget) can support the following layout classes: * FrameLayout * LinearLayout * RelativeLayout And the following widget classes: * AnalogClock * Button * Chronometer * ImageButton * ImageView * ProgressBar * TextView Descendants of these classes are not supported. 

因此从这里能够知道,为何在AppWidget里添加EditText会显示LoadError了,由于自己它就不支持这些复杂的 Widget.  函数

疑问1:为何Google Search会有EditText呢? ui

其实这些都是假象,并非AppWidget支持EditText. 
具体怎么回事,我猜有两种状况: 
1.一种确实是EditText但确不是AppWidget 支持的,而是集成到Home里面去了。 
2.最新的SDK 1.6中,显示在桌面的EditText只是一个ImageView,而这个ImageView的背景就是EditText的截图了。咱们点中这个“EditText”后,会调起一个Activity, 
而这个Activity就是复杂输入的EditText,而且会全屏显示。因此咱们就误以会那是一个单纯的EditText.  this

疑问2:HTC Hero Sense UI的人都看到了,它的AppWidget是确实支持复杂Widget的,好比:Bookmark, Widget:ListView/GridView,Twitter Widget:EditText. spa

这些确实是咱们能够看到的,但它是怎么作到的呢?我也很想知道,AppWidget支持到那么强大,甚至超过了自己AP的功能,很抢眼。但不论是怎么实现的,我想人家确定是花了大力气去作到了,我猜测多是将Google 提供的AppWidget进行了比较大的改动。咱们查看一下framework下的appwidget:  code

pjq@gentoo-pjq ~/android/donut $ ls frameworks/base/core/java/android/appwidget/ -lh total 60K -rw-r--r-- 1 pjq users 7.9K 2009-09-29 21:49 AppWidgetHost.java -rw-r--r-- 1 pjq users 12K 2009-09-29 21:49 AppWidgetHostView.java -rw-r--r-- 1 pjq users 14K 2009-09-29 21:49 AppWidgetManager.java -rw-r--r-- 1 pjq users 691 2009-09-29 21:49 AppWidgetProviderInfo.aidl -rw-r--r-- 1 pjq users 5.6K 2009-09-29 21:49 AppWidgetProviderInfo.java -rwxr-xr-x 1 pjq users 6.3K 2009-09-29 21:49 AppWidgetProvider.java -rw-r--r-- 1 pjq users 1.5K 2009-09-29 21:49 package.html 

因此我想HTC必定是将这里给改动了,以支持复杂的Widget,有知道内情的透露一点最好了。

要知道RemoteView的功能不多,特别是对事件处理的能力,都须要经过PendingIntent,传到BroadcastReceiver 去处理。因此这里对一些事件处理也仅限于比较简单事件:好比说:Button Clicked,其它的我好像还没怎么用过,orz…. 对复杂的View:好比ListView(固然这里还不支持,打个比方),ListView里面那么多Item,要设置Listener,要传值,这些 RemoteView都不能像一个单纯的Activity那样处理。

3.实践探索

写这篇文章的时候,我已经实现了在 AppWidget里显示ListView/GridView这些复杂的Widget了,我这里只说显示,并非说我已经能让AppWidget支持 ListView/GridView了。因此我这里更倾向于教你如何在AppWidget里支持显示ListView/GridView这些复杂的 Widget. 

咱们知道AppWidget只支持RemoteView,那哪些Widget是RemoteView呢,我来教你搜一下: 

Code
pjq@gentoo-pjq ~/android/donut/frameworks/base/core/java/android/widget $ grep -i -n -A 1 @remoteview *.java AbsoluteLayout.java:40:@RemoteView AbsoluteLayout.java-41-public class AbsoluteLayout extends ViewGroup { -- AnalogClock.java:39:@RemoteView AnalogClock.java-40-public class AnalogClock extends View { -- Button.java:58:@RemoteView Button.java-59-public class Button extends TextView { -- Chronometer.java:45:@RemoteView Chronometer.java-46-public class Chronometer extends TextView { -- FrameLayout.java:47:@RemoteView FrameLayout.java-48-public class FrameLayout extends ViewGroup { -- ImageButton.java:66:@RemoteView ImageButton.java-67-public class ImageButton extends ImageView { -- ImageView.java:55:@RemoteView ImageView.java-56-public class ImageView extends View {如今没什么问题。 -- LinearLayout.java:44:@RemoteView LinearLayout.java-45-public class LinearLayout extends ViewGroup { -- ProgressBar.java:122:@RemoteView ProgressBar.java-123-public class ProgressBar extends View { -- RelativeLayout.java:66:@RemoteView RelativeLayout.java-67-public class RelativeLayout extends ViewGroup { -- TextView.java:186:@RemoteView TextView.java-187-public class TextView extends View implements ViewTreeObserver.OnPreDrawListener { 
就是这些了,类名前面加了”@RemoteView”,和我前面列出的那些是否是同样的呢?–对了,就是这些了,因此之后你想知道你在AppWidget支持哪些Widget就能够像我这样去搜一下就知道了,这样最适时。 

写到这里我已经将最关键的内容都已经写出来了,还不明白? 

其实简单点讲就是在一个Widget类前面加上”@RemoteView”,加上了它就等于说RemoteView能够支持它, RemoteView支持就等因而AppWidget支持这它了。 

好了,如今你只须要自定义一些你须要的Widget,加上”@RemoteView”标记,你就能够在AppWidget里使用它了。 

关于如何自定义一个Widget你彻底能够参照frameworks/base/core/java/android/widget已有的这些Widget.依样加一个。 

其实若是你须要自定义一个Widget,好比说支持ListView,你能够先在一个activity里实现它,而后将它移到framework下面去。 

这里说一下可能须要注意的地方: 

1.若是有多个文件,须要Package的时候,名字最好按照这样的形式:android.widget.bookmark 

其中bookmark就是你要添加一个Widget存放的地方,这样的话你就能够在frameworks/base/core/java/android/widget 目录下新增bookmark文件夹,将java文件放在这个目录下。 

若是你新增的Widget只有一个java文件就能够不用这样了,能够彻底按照已经存在的Widget的样子,直接将java文件放到frameworks/base/core/java/android/widget目录下。 

2.资源文件存放: 

frameworks/base/core/res/res 

资源文件都放到这个目录下。 

3.资源的引用: 

要用这样的方式引用:com.android.internal.R.drawable.** 

4.记着在这个Customer Widget类名前加上”@RemoteView”标记. 

这些都作完了,你就已经将一个自定义的Widget添加到framework了。以后要作的工做就是编译整个工程了,从新生成SDK。 

最后你就能够在AppWidget引用你新加的这个Widget了:com.widget.bookmark.***。 

至此,你已经用上了你新加的这个Widget,而且能够加到AppWidget. 

在新加Widget的时候可能会遇到的一些问题: 

1.构造函数初始化问题。 

若是在XML里写的layout不能直接指定哪一个构造函数进行初始化,若是你不肯定会跑哪一个构造函数,最好在每一个构造函数里对加上log,这样你就知道初始化时会跑哪一个构造函数,并将初始化的工做加到里面。我当时就遇到了这个问题,由于用XML写layout,你不能显示调用哪一个构造函数进行初始化,若是你将初始化的操做放到一个不会自动跑到的构造函数里面,那面你运行的时候就好像没添加到Widget同样。 

相关文章
相关标签/搜索