本章继续讲述在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)服务简介

AServiceis 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中注册,注册代码如下:

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

启动服务:

IntentstartIntent=newIntent(MainActivity.this,MusicManageService.class);

startService(startIntent);

停止服务:

IntentstartIntent=newIntent(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

更多相关文章

  1. Android平台中Wifi的初始化
  2. android图片上传服务器
  3. Android——发送和接收广播
  4. android API之ActivityGroup
  5. Android线程封装基类Thread
  6. android AndroidManifest.xml文件解析
  7. Android提权代码zergRush分析
  8. 【Android(安卓)界面效果43】Android(安卓)LayoutInflater的infl
  9. Android从零开始(十五)

随机推荐

  1. Android(安卓)隐藏系统状态栏和标题栏
  2. android GPS 获取位置
  3. IDEA Android(安卓)studio toString() 生
  4. android:largestWidthLimitDp
  5. SDK/ADT历史版本
  6. android 禁止横竖版切换
  7. android 通过资源文件名称获取资源文件id
  8. Android(安卓)改变AlertDialog的大小
  9. Android(安卓)Gradle 基础认识
  10. android ndk 入门实践