android 界面設計基本知識Ⅲ


  本章繼續講述在android界面設計中相關的知識點。介紹內容包括BroadcastReceiver(廣播),Service(服務),Widget(小部件),WebView(網頁加載控件)。

1.BroadcastReceiver

(1)廣播簡介

 在Android中,Broadcast是一種廣泛運用的在應用程序之間傳輸信息的機制。而BroadcastReceiver是對發送出來的 Broadcast進行過濾接受並響應的一類組件。

廣播接收者( BroadcastReceiver )用於接收廣播 Intent ,廣播 Intent 的發送是通過調用 Context.sendBroadcast() 、 Context.sendOrderedBroadcast() 來實現的。通常一個廣播 Intent 可以被訂閱了此 Intent 的多個廣播接收者所接收。

(2)廣播機制

  首先在需要發送信息的地方,把要發送的信息和用於過濾的信息(如Action、Category)裝入一個Intent對象,然后通過調用 sendOrderBroadcast()或sendStickyBroadcast()方法,把 Intent對象以廣播方式發送出去。

當Intent發送以后,所有已經注冊的BroadcastReceiver會檢查注冊時的IntentFilter是否與發送的Intent 相匹配,若匹配則就會調用BroadcastReceiver的onReceive()方法。所以當我們定義一個BroadcastReceiver的時候,都需要實現onReceive()方法。

(3)廣播注冊

  • 靜態注冊:在AndroidManifest.xml中用標簽生命注冊,並在標簽內用標簽設置過濾器。例如:

  <receiver android:name="myRecevice">    //繼承BroadcastReceiver,重寫onReceiver方法

    <intent-filter>    

      <action android:name="com.dragon.net"></action> //使用過濾器,接收指定action廣播

      </intent-filter>

  </receiver> 

  • 動態注冊:

  IntentFilter intentFilter = new IntentFilter();

  intentFilter.addAction(String);   //為BroadcastReceiver指定action,使之用於接收同action的廣播

      registerReceiver(BroadcastReceiver,intentFilter);

  一般:在onStart中注冊,onStop中取消unregisterReceiver

  指定廣播目標Action:Intent intent = new Intent(actionString);

  並且可通過Intent攜帶消息 :intent.putExtra("msg", "hi,我通過廣播發送消息了");

2.Service

(1)服務簡介

  A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.

  翻譯過來就是:Service(服務)是一個沒有用戶界面的在后台運行執行耗時操作的應用組件。其他應用組件能夠啟動Service,並且當用戶切換到另外 的應用場景,Service將持續在后台運行。另外,一個組件能夠綁定到一個service與之交互(IPC機制),例如,一個service可能會處理 網絡操作,播放音樂,操作文件I/O或者與內容提供者(content provider)交互,所有這些活動都是在后台進行。

Service有兩種狀態,“啟動的”和“綁定”。Service生命周期流程如下圖所示:

(2)啟動方式

  • startService 啟動的服務:主要用於啟動一個服務執行后台任務,不進行通信。停止服務使用stopService;
  • bindService 啟動的服務:該方法啟動的服務可以進行通信。停止服務使用unbindService;
  • startService 同時也 bindService 啟動的服務:停止服務應同時使用stepService與unbindService

  綁定狀態的service,通過調用bindService()來啟動,一個綁定的service提供一個允許組件與service交互的接 口,可以發送請求、獲取返回結果,還可以通過誇進程通信來交互(IPC)。綁定的service只有當應用組件綁定后才能運行,多個組件可以綁定一個 service,當調用unbind()方法時,這個service就會被銷毀了。

(3)使用方法

注冊Service,啟動Service,在AndroidManifest.xml中注冊,注冊代碼如下:

  <service android:name="com.example.trywidgetsimplest.MusicManageService" ></service

啟動服務:

              Intent startIntent = new Intent(MainActivity.this,MusicManageService.class);  

              startService(startIntent); 

停止服務:

             Intent startIntent = new Intent(MainActivity.this,MusicManageService.class); 

             stopService(startIntent); 

綁定服務:

綁定服務,便於數據交互或者訪問其中的一些方法:
        public boolean bindService(Intent intent, ServiceConnection conn, int flags) ;
        public void unbindService(ServiceConnection conn);
        intent是跳轉到service的intent,如 Intent intent = new Intent();intent.setClass(this,MyService.class);
        conn則是一個代表與service連接狀態的類,當我們連接service成功或失敗時,會主動觸發其內部的onServiceConnected或onServiceDisconnected方法。訪問service中的數據,可以在onServiceConnected()方法中進行實現。

(4)注意事項

  • 在調用 bindService 綁定到Service的時候,應當保證在某處調用 unbindService 解除綁定(盡管 Activity 被 finish 的時候綁定會自動解除,並且Service會自動停止);
  • 使用 startService 啟動服務之后,一定要使用 stopService停止服務,不管你是否使用bindService;
  • 使用 startService 與 bindService 要注意到,Service 的終止,需要unbindService與stopService同時調用,才能終止 Service,不管 startService 與 bindService 的調用順序,如果先調用 unbindService 此時服務不會自動終止,再調用 stopService 之后服務才會停止,如果先調用 stopService 此時服務也不會終止,而再調用 unbindService 或者之前調用 bindService 的 Context 不存在了(如Activity 被 finish 的時候)之后服務才會自動停止;
  • 當在旋轉手機屏幕的時候,當手機屏幕在“橫”“豎”變換時,此時如果你的 Activity 如果會自動旋轉的話,旋轉其實是 Activity 的重新創建,因此旋轉之前的使用 bindService 建立的連接便會斷開(Context 不存在了),對應服務的生命周期與上述相同。

3.Widget

(1)Widget簡介

  App Widget是應用程序窗口小部件(Widget)是微型的應用程序視圖,它可以被嵌入到其它應用程序中(比如桌面)並接收周期性的更新。你可以通過一個App Widget Provider來發布一個Widget。

(2)Widget應用

appwidget-provider標簽:

這個玩意是用來定義桌面widget的大小,初始狀態等等信息的,它的位置應該放在res/xml文件夾下,具體的xml參數如下:

  • android:minWidth : 最小寬度
  • android:minHeight : 最小高度
  • android:updatePeriodMillis : 更新widget的時間間隔(ms),"86400000"為1個小時
  • android:previewImage : 預覽圖片
  • android:initialLayout : 加載到桌面時對應的布局文件
  • android:resizeMode : widget可以被拉伸的方向。horizontal表示可以水平拉伸,vertical表示可以豎直拉伸
  • android:widgetCategory : widget可以被顯示的位置。home_screen表示可以將widget添加到桌面,keyguard表示widget可以被添加到鎖屏界面
  • android:initialKeyguardLayout : 加載到鎖屏界面時對應的布局文件

示例XML
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
  android:minWidth="40dp"
  android:minHeight="40dp"
  android:updatePeriodMillis="86400000"
  android:previewImage="@drawable/preview"
  android:initialLayout="@layout/example_appwidget"
  android:configure="com.example.android.ExampleAppWidgetConfigure" 
  android:resizeMode="horizontal|vertical"
  android:widgetCategory="home_screen|keyguard"
  android:initialKeyguardLayout="@layout/example_keyguard">
</appwidget-provider>

示例說明

  • minWidth 和minHeight

   它們指定了App Widget布局需要的最小區域。缺省的App Widgets所在窗口的桌面位置基於有確定高度和寬度的單元網格中。如果App Widget的最小長度或寬度和這些網格單元的尺寸不匹配,那么這個App Widget將上舍入(上舍入即取比該值大的最接近的整數)到最接近的單元尺寸。注意:app widget的最小尺寸,不建議比 “4x4” 個單元格要大。關於app widget的尺寸,后面在詳細說明。

  • minResizeWidth 和 minResizeHeight  

  它們屬性指定了 widget 的最小絕對尺寸。也就是說,如果 widget 小於該尺寸,便會因為變得模糊、看不清或不可用。 使用這兩個屬性,可以允許用戶重新調整 widget 的大小,使 widget 的大小可以小於 minWidth 和 minHeight。注意:當 minResizeWidth 的值比 minWidth 大時,minResizeWidth 無效;當 resizeMode 的取值不包括 horizontal 時,minResizeWidth 無效。當 minResizeHeight 的值比 minHeight 大時,minResizeHeight 無效;當 resizeMode 的取值不包括 vertical 時,minResizeHeight 無效。

  • updatePeriodMillis  

   它定義了 widget 的更新頻率。實際的更新時機不一定是精確的按照這個時間發生的。建議更新盡量不要太頻繁,最好是低於1小時一次。 或者可以在配置 Activity 里面供用戶對更新頻率進行配置。 實際上,當updatePeriodMillis的值小於30分鍾時,系統會自動將更新頻率設為30分鍾!關於這部分,后面會詳細介紹。
  注意: 當更新時機到達時,如果設備正在休眠,那么設備將會被喚醒以執行更新。如果更新頻率不超過1小時一次,那么對電池壽命應該不會造成多大的影響。 如果你需要比較頻繁的更新,或者你不希望在設備休眠的時候執行更新,那么可以使用基於 alarm 的更新來替代 widget 自身的刷新機制。將 alarm 類型設置為 ELAPSED_REALTIME 或 RTC,將不會喚醒休眠的設備,同時請將 updatePeriodMillis 設為 0。

  • initialLayout   

  指向 widget 的布局資源文件

  • configure  

  可選屬性,定義了 widget 的配置 Activity。如果定義了該項,那么當 widget 創建時,會自動啟動該 Activity。

  • previewImage  

  指定預覽圖,該預覽圖在用戶選擇 widget 時出現,如果沒有提供,則會顯示應用的圖標。該字段對應在 AndroidManifest.xml 中 receiver 的 android:previewImage 字段。由 Android 3.0 引入。

  • autoAdvanceViewId   

  指定一個子view ID,表明該子 view 會自動更新。在 Android 3.0 中引入。

  • resizeMode 

  指定了 widget 的調整尺寸的規則。可取的值有: "horizontal", "vertical", "none"。"horizontal"意味着widget可以水平拉伸,“vertical”意味着widget可以豎值拉伸,“none”意味着 widget不能拉伸;默認值是"none"。Android 3.1 引入。

  • widgetCategory   

  指定了 widget 能顯示的地方:能否顯示在 home Screen 或 lock screen 或 兩者都可以。它的取值包括:"home_screen" 和 "keyguard"。Android 4.2 引入。

  • initialKeyguardLayout 

  指向 widget 位於 lockscreen 中的布局資源文件。Android 4.2 引入。

AppWidgetProvider類:

  通過appwidget-provider標簽就可以得到初始化的布局,視圖等,但widget要實時更新時,要響應用戶操作時,就需要額外的類來輔助處理了,這個類就是AppWidgetProvider。由於AppWidgetProvider要接收到當前widget的狀態(是否被添加,是否被刪除等),所以要接收通知,必然是派生自BroadcastReceiver。

AppWidgetProvider中的廣播處理函數如下:(根據不同的使用情況,重寫不同的函數)

  • onUpdate():

  在3種情況下會調用OnUpdate()。onUpdate()是在main線程中進行,因此如果處理需要花費時間多於10秒,處理應在service中完成。(第二篇會講為什么還要有service)

  1. 在時間間隔到時調用,時間間隔在widget定義的android:updatePeriodMillis中設置;
  2.   用戶拖拽到主頁,widget實例生成。無論有沒有設置Configure activity,我們在Android4.4的測試中,當用戶拖拽圖片至主頁時,widget實例生成,會觸發onUpdate(),然后再顯示 activity(如果有)。這點和資料說的不一樣,資料認為如果設置了Configure acitivity,就不會在一開始調用onUpdate(),而實驗顯示當實例生成(包括創建和重啟時恢復),都會先調用onUpate()。在本例, 由於此時在preference尚未有相關數據,創建實例時不能有效進行數據設置。
  3. 機器重啟,實例在主頁上顯示,會再次調用onUpdate()
  • onDeleted(Context, int[]):

  當 widget 被刪除時被觸發。

  • onEnabled(Context):

  當第1個 widget 的實例被創建時觸發。也就是說,如果用戶對同一個 widget 增加了兩次(兩個實例),那么onEnabled()只會在第一次增加widget時觸發。

  • onDisabled(Context):

  當最后1個 widget 的實例被刪除時觸發。

  • onReceive(Context, Intent):

  在接收到廣播時,調用。

(3)Widget布局

  在 AppWidgetProviderInfo中已經介紹了,minWidth 和minHeight 用來指定了App Widget布局需要的最小區域。缺省的App Widgets所在窗口的桌面位置基於有確定高度和寬度的單元網格中。如果App Widget的最小長度或寬度和這些網格單元的尺寸不匹配,那么這個App Widget將上舍入(上舍入即取比該值大的最接近的整數——譯者注)到最接近的單元尺寸。
例如,很多手機提供4x4網格,平板電腦能提供8x7網格。當widget被添加到時,在滿足minWidth和minHeight約束的前提下,它將被占領的最小數目的細胞。

粗略計算minWidth和minHeight,可以參考下面表格:

單元格個數
(行 / 列)
對應的設置大小 (dp)
(minWidth / minHeight)
1 40dp
2 110dp
3 180dp
4 250dp
n 70 × n − 30

詳細計算minWidth和minHeight,要計算各個區域的大小。以下圖為例:

計算結果
minWidth = 144dp + (2 × 8dp) + (2 × 56dp) = 272dp
minHeight = 48dp + (2 × 4dp) = 56dp

(4)Widget支持的布局和控件

Widget並不支持所有的布局和控件,而僅僅只是支持Android布局和控件的一個子集。

  • App Widget支持的布局 

   FrameLayout

 LinearLayout

   RelativeLayout

  GridLayout

  •  App Widget支持的控件

  AnalogClock

  Button            

  Chronometer

  ImageButton

  ImageView

  ProgressBar

  TextView

  ViewFlipper

  ListView

  GridView

  StackView

  AdapterViewFlipper

除此之外的所有控件(包括自定義控件)都無法顯示,無法顯示時,添加出來的widget會顯示“加載布局出錯”

4.WebView

 

5.參考引用

Widget文檔參考:

http://blog.csdn.net/harvic880925/article/details/41445407

http://blog.csdn.net/sasoritattoo/article/details/17616597

Service文檔參考:

http://www.cnblogs.com/yejiurui/p/3429451.html

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM