1.题记
Android中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。
广播接收者(BroadcastReceiver)用于接收广播Intent,广播Intent的发送是通过调用Context.sendBroadcast()、Context.sendOrderedBroadcast()来实现的。通常一个广播Intent可以被订阅了此Intent的多个广播接收者所接收,这个特性跟JMS中的Topic消息接收者类似。
2.Service开发详解
服务的开发比较简单,如下:
第一步:继承Service类
public class SMSService extends Service { }
第二步:在AndroidManifest.xml文件中的<application>节点里对服务进行配置:
<service android:name=".SMSService" />
服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法都可以启动Service,但是它们的使用场合有所不同。使用startService()方法启用服务,访问者与服务之间没有关连,即使访问者退出了,服务仍然运行。使用bindService()方法启用服务,访问者与服务绑定在了一起,访问者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。
采用Context.startService()方法启动服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。
startService 与 bindService区别如下:
- 生命周期:startService方式启动,Service是通过接受Intent并且会经历onCreate和onStart。当用户在发出意图使之销毁时会经历onDestory而bindService方式启动,与Activity绑定的时候,会经历onCreate和onBind,而当Activity被销毁的时候,Service会先调用onUnbind然后是onDestory.
- 控制方式:牵着的控制方式需要使用固定的方法,对Service进行单一的操作。而后者由于与Activity绑定,不用考虑其生命周期问题,并且从发送Intent的被动操作,变为可以主动对Service对象进行操作,我们深圳可以建立一个Handler类,对Service进行相关的操作。大大加强了Service的灵活性、可操作性。
- 总结:对于简单的应用startService启动方式能带来更少的代码,简单的操作,对于复杂的应用bindService方式,虽然带来的更多的编码,但同时也带来了更好的可操作性,使其实用起来更像Activity。
3.BroadcastReceiver开发详解
3.1BroadcastReceiver广播接收者
要实现一个广播接收者方法如下:
第一步:继承BroadcastReceiver,并重写onReceive()方法。
public class IncomingSMSReceiver extends BroadcastReceiver {
@Override public void onReceive(Context context, Intent intent) {
}
}
第二步:订阅感兴趣的广播Intent,订阅方法有两种:
第一种:使用代码进行订阅
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
IncomingSMSReceiver receiver = new IncomingSMSReceiver();
registerReceiver(receiver, filter);
第二种:在AndroidManifest.xml文件中的<application>节点里进行订阅:
<receiver android:name=".IncomingSMSReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
广播被分为两种不同的类型:“普通广播(Normal broadcasts)”和“有序广播(Ordered broadcasts)”。普通广播是完全异步的,可以在同一时刻(逻辑上)被所有接收者接收到,消息传递的效率比较高,但缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播;然而有序广播是按照接收者声明的优先级别,被接收者依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,最后传给C 。优先级别声明在intent-filter元素的android:priority属性中,数越大优先级别越高,取值范围:-1000到1000,优先级别也可以调用IntentFilter对象的setPriority()进行设置 。有序广播的接收者可以终止广播Intent的传播,广播Intent的传播一旦终止,后面的接收者就无法接收到广播。另外,有序广播的接收者可以将数据传递给下一个接收者,如:A得到广播后,可以往它的结果对象中存入数据,当广播传给B时,B可以从A的结果对象中得到A存入的数据。
Context.sendBroadcast()
发送的是普通广播,所有订阅者都有机会获得并进行处理。
Context.sendOrderedBroadcast()
发送的是有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者,前面的接收者有权终止广播(BroadcastReceiver.abortBroadcast()),如果广播被前面的接收者终止,后面的接收者就再也无法获取到广播。对于有序广播,前面的接收者可以将数据通过setResultExtras(Bundle)方法存放进结果对象,然后传给下一个接收者,下一个接收者通过代码:Bundle bundle = getResultExtras(true))可以获取上一个接收者存入在结果对象中的数据。
系统收到短信,发出的广播属于有序广播。如果想阻止用户收到短信,可以通过设置优先级,让你们自定义的接收者先获取到广播,然后终止广播,这样用户就接收不到短信了。
3.2广播接收者的响应
在Android中,每次广播消息到来时都会创建BroadcastReceiver实例并执行onReceive() 方法, onReceive() 方法执行完后,BroadcastReceiver 的实例就会被销毁。当onReceive() 方法在10秒内没有执行完毕,Android会认为该程序无响应。所以在BroadcastReceiver里不能做一些比较耗时的操作,否侧会弹出ANR(Application No Response)的对话框。如果需要完成一项比较耗时的工作,应该通过发送Intent给Service,由Service来完成。这里不能使用子线程来解决,因为BroadcastReceiver的生命周期很短,子线程可能还没有结束BroadcastReceiver就先结束了。BroadcastReceiver一旦结束,此时BroadcastReceiver的所在进程很容易在系统需要内存时被优先杀死,因为它属于空进程(没有任何活动组件的进程)。如果它的宿主进程被杀死,那么正在工作的子线程也会被杀死。所以采用子线程来解决是不可靠的。
public class IncomingSMSReceiver extends BroadcastReceiver {
@Override public void onReceive(Context context, Intent intent) {
//发送Intent启动服务,由服务来完成比较耗时的操作
Intent service = new Intent(context, XxxService.class);
context.startService(service);
}
}
3.3常见系统广播接收者
除了短信到来广播Intent,Android还有很多广播Intent,如:开机启动、电池电量变化、时间已经改变等广播Intent。
接收电池电量变化广播Intent ,在AndroidManifest.xml文件中的<application>节点里订阅此Intent:
<receiver android:name=".IncomingSMSReceiver">
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED"/>
</intent-filter>
</receiver>
接收开机启动广播Intent,在AndroidManifest.xml文件中的<application>节点里订阅此Intent:
<receiver android:name=".IncomingSMSReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
并且要进行权限声明:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
接收短信广播Intent,在AndroidManifest.xml文件中的<application>节点里订阅此Intent:
<receiver android:name=".IncomingSMSReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
在AndroidManifest.xml文件中添加以下权限:
<uses-permission android:name="android.permission.RECEIVE_SMS"/><!-- 接收短信权限 -->
<uses-permission android:name="android.permission.SEND_SMS"/><!-- 发送短信权限 -->
4.简单实例
下面是整合了Service与BroadCastReceiver的一个小例子,主要实现的是,在后台开通一个计数服务,当计数能被5整除时候则广播该数。主要代码如下:
ClientActivity绑定服务:
public class ClientActivity extends Activity {
/** Called when the activity is first created. */
private ICountService countService;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.bindService(new Intent(this, CountService.class),
this.serviceConnection, BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
this.unbindService(serviceConnection);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_BACK)
{
this.unbindService(serviceConnection);
this.finish();
return true;
}
return super.onKeyUp(keyCode, event);
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
countService = (ICountService) service;// 对于本地服务,获取的实例和服务onBind()返回的实例是同一个
int i = countService.getCount();
Log.v("CountService", "Count is " + i);
}
@Override
public void onServiceDisconnected(ComponentName name) {
countService = null;
}
};
}
计数服务代码:
package com.sulang.android.service;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
/*
*@author 七里香的悔恨,2011-3-17
*CountService.java
*Blog:[url]http://bigboy.iteye.com/[/url]
*/
public class CountService extends Service {
private boolean quit=false;
private int count;
private ServiceBinder serviceBinder = new ServiceBinder();
private final static String DIVIDE_RESULT="com.sulang.android.service.DIVIDE";
@Override
public IBinder onBind(Intent intent) {
return serviceBinder;
}
public class ServiceBinder extends Binder implements ICountService {
@Override
public int getCount() {
return count;
}
}
@Override
public void onCreate() {
super.onCreate();
new Thread(new Runnable() {
@Override
public void run() {
while (!quit) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
count++;
if(count%5==0)
{
Intent intent = new Intent(DIVIDE_RESULT);
intent.putExtra("count", count);
sendBroadcast(intent);
}
Log.i("CountService", count+"");
}
}
}).start();
}
@Override
public void onDestroy() {
super.onDestroy();
this.quit = true;
}
}
计数广播接收者:
package com.sulang.android.service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
/*
*@author 七里香的悔恨,2011-3-18
*CountServiceBroadcast.java
*Blog:[url]http://bigboy.iteye.com/[/url]
*/
public class CountServiceBroadcast extends BroadcastReceiver {
private final static String DIVIDE_RESULT="com.sulang.android.service.DIVIDE";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals(DIVIDE_RESULT))
{
int count = intent.getIntExtra("count", 0);
Toast.makeText(context, "当前数字为:"+count, Toast.LENGTH_LONG).show();
}
}
/**
* 使用代码进行订阅广播
* IntentFilter filter=new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
* IncomingSMSReceiver receiver=new IncomingSMSReceiver();
* registerReceiver(receiver,filter);
*/
}
manifest文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sulang.android.service"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="4" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".ClientActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".CountService">
<intent-filter>
<action android:name="com.sulang.android.service.Count"></action>
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</service>
<receiver android:name=".CountServiceBroadcast">
<intent-filter>
<action android:name="com.sulang.android.service.DIVIDE" />
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</receiver>
</application>
</manifest>
具体效果图如下:
源代码见附件
- 大小: 6.4 KB
分享到:
相关推荐
在Android开发中,服务(Service)、广播接收器(BroadcastReceiver)和通知(Notification)是三个核心组件,它们各自承担着不同的职责,同时在特定场景下相互配合,为应用程序提供后台运行、事件监听和用户交互的...
在Android应用开发中,Intent、Activity、Service以及BroadcastReceiver是四大核心组件,它们构成了Android应用程序的基本骨架。下面将详细介绍这四个关键概念。 1. **Intent(意图)**: Intent在Android中扮演着...
android service Notification BroadcastReceiver Intent 安装的服务开机自启动,service定时的打印消息,消息同时显示在通知栏,窗体界面的跳转,自定义控件的开发。系统广播,定时广播,轮询广播等。...
Android Service与BroadcastReceiver、bindService示例详解,代码非常详细,详解博客网址:http://blog.csdn.net/sunboy_2050/article/details/7364024
在Android开发中,`BroadcastReceiver`(广播接收者)和`Service`是两个非常重要的组件。它们各自扮演着系统通信和后台操作的关键角色。在这个例子中,我们将深入探讨这两个组件的使用,以及如何将它们结合在一起...
Android 使用Service和BroadcastReceiver实现音乐播放功能 Service demo中service使用得是新的进程,activity和service日志需要切换进程才能看到,这里是最典型得activity和service交互的过程, activity传递信息很简单...
这份资料“初中级Android开发社招面试之Service及BroadcastReceiver”显然是针对想要深入理解这两个概念的开发者,特别是对于正在寻找Android开发职位的求职者。 **Service** Service是Android系统中的一个组件,...
Service是Android系统中的一种组件,主要用于在后台执行长时间运行的操作,而BroadcastReceiver则是接收系统或应用程序广播消息的组件。在Android开发中,理解和熟练运用Service和BroadcastReceiver是至关重要的。 ...
在Android系统中,四大组件是应用程序的核心组成部分,包括Activity、Service、Content Provider和BroadcastReceiver。本篇文章将聚焦于BroadcastReceiver,讲解如何在Android应用中使用它,特别是静态注册和动态...
在Android系统中,BroadcastReceiver(广播接收者)是四大组件之一,它扮演着接收系统或应用广播消息的重要角色。BroadcastReceiver使得应用可以在不运行的情况下,响应系统或其它应用发出的事件,例如系统启动完成...
Service是Android四大组件之一,用于在后台执行长时间运行的任务,即使用户不在与应用交互,Service也会继续运行。通常,Service用于处理音乐播放、网络通信等长时间操作。 在我们的实例中,"先启动service"意味着...
在Android系统中,BroadcastReceiver(广播接收者)是四大组件之一,它负责监听系统或应用程序发布的广播消息。BroadcastReceiver能够使应用在不运行的情况下对特定事件做出响应,从而实现跨应用通信。本示例将详细...
Android 的四大组件之一是 Service,Service 是 Android 中的一种组件,用于在后台运行程序,承担着静悄悄的不为人所注意的工作。Service 可以在很多场合的应用中使用,比如播放多媒体的时候用户启动了其他 ...
在Android系统中,广播BroadcastReceiver是一种非常重要的组件,它允许应用程序接收并响应系统或自定义广播事件。广播是Android系统中的一种全局通知机制,当某个事件发生时,系统会发送一个广播,所有注册了该事件...
在Android应用开发中,`Service`和`Activity`是两个重要的组件。`Service`用于在后台执行长时间运行的任务,而`Activity`则负责用户界面交互。在某些场景下,我们可能需要在`Service`和`Activity`之间传递数据,比如...
在Android应用开发中,Service是四大组件之一,用于在后台长时间运行操作,比如播放音乐、网络通信等。然而,如果不加以控制,用户或者系统可能会多次启动同一个Service,导致不必要的资源消耗和服务的异常行为。本...
播放音乐,我们需要在AndroidManifest.xml文件添加权限 创建Service,需要在AndroidManifest.xml文件配置 现在我们创建了一个叫做MusicService的...import androidx.appcompat.app.AppCompatActivity; import an