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呢,我來教你搜一下:
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 {
寫到這裏我已經將最關鍵的內容都已經寫出來了,還不明白?
其實簡單點講就是在一個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同樣。