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)
- 在时间间隔到时调用,时间间隔在widget定义的android:updatePeriodMillis中设置;
- 用户拖拽到主页,widget实例生成。无论有没有设置Configure activity,我们在Android4.4的测试中,当用户拖拽图片至主页时,widget实例生成,会触发onUpdate(),然后再显示 activity(如果有)。这点和资料说的不一样,资料认为如果设置了Configure
acitivity,就不会在一开始调用onUpdate(),而实验显示当实例生成(包括创建和重启时恢复),都会先调用onUpate()。在本例, 由于此时在preference尚未有相关数据,创建实例时不能有效进行数据设置。 - 机器重启,实例在主页上显示,会再次调用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
android 界面设计基本知识Ⅲ的更多相关文章
- android 界面设计基本知识Ⅱ
上一章讲述了Android界面设计时,一些基本控件的使用,本章主要讲述自定义控件,Fragment和Headler线程机制. 1.自定义控件 (1)基本知识 dp.sp和dx px:像素点 ...
- android 界面设计基本知识
一个好的APP不仅有美观,好看的界面,更需要良好的性能和稳定性.作为一名开发人员,需要理解界面设计原则并写出优秀的界面设计代码. 本章主要讲述基本控件的使用,界面布局及一些常用的界面设计属性. 1.常 ...
- android界面设计之布局管理
谈到android界面设计,各种布局样式不得不提!传统的布局方式有6种,我们会一一介绍. 在android studio2.2版本之后出现了一款超棒的布局方式,真正意义上的所见即所得,后面我们也会讲到 ...
- Android界面设计适配不同屏幕的尺寸和密度解读
Android是运行在各种提供不同的屏幕尺寸和密度的设备.Android系统提供跨设备的统一开发环境和处理大部分的工作,以调整每个应用程序的用户界面,以在其上显示的画面. 同时,该系统提供了API,允 ...
- Android界面布局基本知识简述
Android手机操作系统在模拟器中进行相关的编写,可以帮助我们实现各种功能需求.尤其是在界面的操作方面显得更为突出.在这里我们就可以对Android界面布局的相关操作来对这方面的知识进行一个深入的了 ...
- Android界面设计之对话框——定制Toast、AlertDialog
一.概述 在界面设计中需要根据用户操作显示提示信息.出错信息等,就要用到对话框.Android实现提示信息显示常用有两种方式 1.Toast 2.AlertDialog 二.Toast Android ...
- 让你大开眼界的10款Android界面设计
根据调查显示, iOS与Android的市场份额差距正越来越大.Android设备正在成为手机应用市场的主力军.如何从设计层面创造一个优美的app界面来吸引用户已然成为广大App开发者们必做的功课之一 ...
- 第三篇-以LinearLayout进行Android界面设计
一.新建一个项目 选择empty activity,此时项目里面没有main.java的文件. 二.手动创建java文件 Project那儿选择android模式,在app/java/com....一 ...
- 第四篇-以ConstraintLayout进行Android界面设计
此文章基于第三篇. 一.新建一个layout.xml文件,创建方法不再赘述,在Design界面右击LinearLayout,点击Convert LinearLayout to ConstraintLa ...
随机推荐
- 音频文件解析(二):WAV格式文件波形绘制
解析WAV头部信息后,接下来就可以根据相关参数和DATA块数据绘制波形. 1.重新编码(转换为8bits,单声道数据) Public Function GetFormatData(ByVal pDat ...
- Python访问剪切板
剪切板访问工具 ----pyperclip he purpose of Pyperclip is to provide a cross-platform Python module for copyi ...
- Wo的书单
一个人,一生之中总要有几本证明自己的书. 2016---08 <ASP.NET MVC5 高级编程(第五版)> <数据结构(C语言第二版)>
- 一行代码实现js数组去重
console.log([...new Set([1,2,3,4,2,1,2,2,2,167,4,3,32,2,1])])
- Web API应用支持HTTPS的经验总结
在我前面介绍的WebAPI文章里面,介绍了WebAPI的架构设计方面的内容,其中提出了现在流行的WebAPI优先的路线,这种也是我们开发多应用(APP.微信.微网站.商城.以及Winform等方面的整 ...
- 快速学习JavaScript面向对象编程
到处都是属性.方法,代码极其难懂,天哪,我的程序员,你究竟在做什么?仔细看看这篇指南,让我们一起写出优雅的面向对象的JavaScript代码吧! 作为一个开发者,能否写出优雅的代码对于你的职业生涯至关 ...
- 孙鑫MFC学习笔记1.Windows应用程序运行机理
1.MSG结构 hwnd:窗口句柄 message:消息类型 wParam & lParam:消息的附加信息(比如键值) time:消息被投递的时间 tip:typedef的作用是从变量类型区 ...
- java.lang.NoClassDefFoundError: com/google/gson/Gson错误的解决
SSH返回JSON格式的数据时,需要用到gson,将gson-1.6.jar添加进Build path以后运行,出错: 后来把gson-1.6.jar复制到WEB-INF/lib/下再运行,就没再出这 ...
- Focus
在尘世中沉浸得越久,越无法集中精力去做好一件事. 缺乏学习!
- comparator接口与Comparable接口的区别
1. Comparator 和 Comparable 相同的地方 他们都是java的一个接口, 并且是用来对自定义的class比较大小的, 什么是自定义class: 如 public class Pe ...