前言:

我们都知道Android的四大基本组件:Activity、ContentProvider、Service以及BroadcastReceiver,前面的两个我们在前几篇已经具体讲解了,今天这一天我们就把后两者的使用具体说一下,由于Service和BroadcastReceiver常常一起使用,所以我们一起来学习。

一.Service的使用

Service是Android系统的后台服务组件,没有用户界面,但可以长时间的运行,比Activity的优先级高,可以用于进程间的通信。

Service也同Activity一样有自己的生命周期,但是Service有两种生命周期,也就是Service由两种启动以及对应的停止方式:

1.以启动方式使用的Service:

(1)特点:

A.通过Content.startService()启动,Content.stopService()或者Content.stopSelf()来停止;

(即只能通过其他组件启动,但可以自己停止)

B.不能与外部的组件进行交互;

(2)生命周期:

onCreate——>onStartCommand——>onDestroy

(3)示例代码:L0828_Service(记得注册)

MyService.java:

package com.example.l0828_service;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MyService extends Service{
//声明定时器,用于创建新的进程来计时
private Timer timer;
private TimerTask task;
private static int i=;
//继承Service必须要重写的方法onBind
@Override
public IBinder onBind(Intent intent) {
return null;
}
/*Service的生命周期一:onCreate、onStartCommand、onDestroy方法构成*/
//onCreate方法,启动服务,每次启动仅仅调用一次
@Override
public void onCreate() {
System.out.println("onCreate");
super.onCreate();
}
//onStartCommand方法,一般在其中完成Service的工作
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("onStartCommond");
startTimer();
return super.onStartCommand(intent, flags, startId);
}
//onDestroy方法,用来释放Service的资源
@Override
public void onDestroy() {
System.out.println("onDestroy");
stopTimer();
super.onDestroy();
}
//开启定时器
public void startTimer(){
timer =new Timer();
task=new TimerTask(){
@Override
public void run() {
i++;
System.out.println(i);
}
};
timer.schedule(task, , );
}
//停止定时器
public void stopTimer(){
timer.cancel();
}
}

Mainactivity.java:

package com.example.l0828_service;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener{
private Button btn_start,btn_stop;
//声明Intent用于Activity向Service的跳转
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_start=(Button) findViewById(R.id.btn_start);
btn_stop=(Button) findViewById(R.id.btn_stop);
btn_start.setOnClickListener(this);
btn_stop.setOnClickListener(this);
//Activity组件向Service组件的跳转
intent=new Intent(MainActivity.this,MyService.class);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_start:
//开启服务
startService(intent);
break;
case R.id.btn_stop:
//停止服务
stopService(intent);
break;
}
}
}

主配置文件.xml文件中注册:

<service android:name="MyService"></service>

运行效果:

起始界面

点击开始——停止的过程显示:

停止之后再次点击开始按钮又重新执行onCreate方法:

2.以绑定方式使用的Service:

(1)特点:

A.通过Content.bindService()绑定而建立与服务器的连接,通过Content.unbindService()方法解除绑定从而断开与服务器的连接;

B.如果没有调用startService直接通过调用bindService绑定服务器也会自动启动服务器;

C.能获得Service的对象,从而能够使得其他组件与Service的交互;

D.同一个Service可以绑定多个服务连接,同时与不同的组件交互;

(2)生命周期:

onCreate——>onBind——>onCommand——>onUnbind——>onRebind——>onDestroy

如果onUnbind方法返回true,则当取消绑定之后重写绑定服务时就直接调用onRebind方法了。

(3)示例代码:

MyService.java:

package com.example.l0828_service2;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class MyService extends Service{
private Timer timer;
private TimerTask task;
private int i=;
private int j=;
//创建内部类,用于创建Binder对象,onBinder方法中使用
class MyBinder extends Binder{
public MyService getService(){
return MyService.this;
}
}
private MyBinder binder=new MyBinder();
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
} public int getJ() {
return j;
}
public void setJ(int j) {
this.j = j;
}
//下面分别重写Service生命周期的方法
@Override
public IBinder onBind(Intent intent) {
//绑定服务,开始于界面交互
startTimer();
System.out.println("onBind");
return binder;
}
@Override
public void onCreate() {
System.out.println("onCreate");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean onUnbind(Intent intent) {
//解除与服务器的绑定,停止与界面的交互
stopTimer();
System.out.println("onUnbind");
//为了使onRebind能够调用到,使得onUnbind的返回值为true
super.onDestroy();
return true;
}
@Override
public void onRebind(Intent intent) {
System.out.println("onRebind");
super.onRebind(intent);
}
@Override
public void onDestroy() {
System.out.println("onDestroy"); }
//创建定时器,即创建另一个线程负责计时
public void startTimer(){
timer=new Timer();
task=new TimerTask() { @Override
public void run() {
i++;
if(i==j){
System.out.println("此时您输入的数据于服务数据相同:"+j);
}
System.out.println(i);
}
};
timer.schedule(task, ,);
}
//停止计时
public void stopTimer(){
timer.cancel();
}
}

MainActivity.java:

package com.example.l0828_service2;
import com.example.l0828_service2.MyService.MyBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener,ServiceConnection{
private Button btn_bind,btn_unBind,btn_getService,btn_start,btn_stop;
private Intent intent;
private MyService myservice;
private EditText et;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et=(EditText) findViewById(R.id.et);
btn_bind=(Button) findViewById(R.id.btn_bind);
btn_unBind=(Button) findViewById(R.id.btn_unBind);
btn_getService=(Button) findViewById(R.id.btn_getService);
btn_start=(Button) findViewById(R.id.btn_start);
btn_stop=(Button) findViewById(R.id.btn_stop);
btn_bind.setOnClickListener(this);
btn_unBind.setOnClickListener(this);
btn_getService.setOnClickListener(this);
btn_start.setOnClickListener(this);
btn_stop.setOnClickListener(this);
intent=new Intent(MainActivity.this, MyService.class);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_bind:
bindService(intent, this, BIND_AUTO_CREATE);
break;
case R.id.btn_unBind:
unbindService(this);
break;
case R.id.btn_getService:
String info=et.getText().toString();
if("".equals(info)){
Toast.makeText(MainActivity.this,"当前的i值:"+myservice.getI() , Toast.LENGTH_SHORT).show();
}
myservice.setJ(Integer.parseInt(info));
break;
case R.id.btn_start:
startService(intent);
break;
case R.id.btn_stop:
stopService(intent);
break;
}
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyService.MyBinder binder=(MyBinder) service;
myservice=binder.getService();
}
@Override
public void onServiceDisconnected(ComponentName name) { } }

运行效果:

初始界面:

依次点击start、bind、unbind、输入一个服务还未计时到的数、getService、stop的过程:

下图是上面执行过程的输出情况,可以清晰明了的看出整个执行的过程:

下面是这样的执行顺序的结果:

start、bind、输入及时数据、getService、unbind、(正是此时调用了onRebind方法)bind、unbind、stop的过程

二.BroadcastReceiver的使用

1.使用广播实现简单的数据接收功能:

(1)MainActivity.java:

package com.example.l0829_broadcastreceiver;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn_send).setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
//仍然是使用Intent来实现组件之间的跳转
Intent intent=new Intent(MainActivity.this, MyBroadCastReceiver.class);
//把要向广播接收器发送的数据用Intent对象封装,注意键值要相同
intent.putExtra("name", "我接收到了");
//发送数据
sendBroadcast(intent);
}
});
}
}

(2)MyBroadcastReceiver.java:

package com.example.l0829_broadcastreceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
//继承BroadcastReceiver
public class MyBroadCastReceiver extends BroadcastReceiver{
//只需重写OnReceiver方法
@Override
public void onReceive(Context context, Intent intent) {
//接收特定键值的数据,实现广播接收器的基本功能
String str=intent.getStringExtra("name");
System.out.println(str);
}
}

(3)一定不要忘记注册啊(四大基本组件是都需要在主配置文件中注册的):

<receiver android:name="MyBroadCastReceiver"></receiver>

2.再实现一个系统默认广播的例子——电量改变的广播:

(1)MainActivity.java

package com.example.l0829_system_broadcastreceiver;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
//创建一个广播的实例,在其onReceive方法中实现接收的过程
private BroadcastReceiver myBR=new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
//if(Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction()))这里也可以先判断一下,确保正确性
//下面就是接收系统当前电量信息的过程,注意这里的键值level和scale是系统固定值,不能改变
int level=intent.getIntExtra("level", );
int scale=intent.getIntExtra("scale", );
tv.setText("当前电量:"+level*/scale+"%");
}
};
//声明一个TextView用来显示接受的当前电量值
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView) findViewById(R.id.tv_receive);
//动态注册广播的方法,在onCreate方法中
registerReceiver(myBR, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
@Override
protected void onStop() {
//在onStop方法中取消广播的注册
unregisterReceiver(myBR);
super.onStop();
}
}

(2)由于在代码中实现了Receiver的动态注册,那么主配置文件中就不用注册了

(3)运行效果:(有点小哈,凑合看看吧)

(另外有一个温馨提示:模拟器的电量值永远是50%,可以用真机测试)

3.最后算是来个总结吧:

我们实现一个Activity、Service、BroadcastReceiver三大组件结合使用的例子,完成Service始终在后台计时、BroadcastReceiver接收数据并及时更新主Activity的过程:

(1)MyService.java

package com.example.l0829_zujian_all;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MyService extends Service{
private Timer timer;
private TimerTask task;
private int i=;
private Intent intent;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
@Override
public void onCreate() {
//开始服务
startTimer();
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
@Override
public void onRebind(Intent intent) {
super.onRebind(intent);
}
@Override
public void onDestroy() {
//停止服务
stopTimer();
super.onDestroy();
}
public void startTimer(){
timer=new Timer();
task=new TimerTask() { @Override
public void run() {
i++;
//在计时器中及时向ACTION_MY的BroadcastReceiver接收器中发送键值为id的数据
intent=new Intent();
intent.setAction("ACTION_MY");
intent.putExtra("id", i);
sendBroadcast(intent);
}
};
timer.schedule(task, ,);
}
public void stopTimer(){
timer.cancel();
}
}

(2)MainActivity.java

package com.example.l0829_zujian_all;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener{
//创建接收器对象,并在onReceive方法中接收键值为id的数据
private BroadcastReceiver br=new BroadcastReceiver() { @Override
public void onReceive(Context context, Intent intent) {
int val=intent.getIntExtra("id", );
System.out.println(intent.getIntExtra("id", ));
tv_show.setText(val+"");
}
};
private Button btn_start,btn_stop;
private TextView tv_show;
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_show=(TextView) findViewById(R.id.tv_show);
btn_start=(Button) findViewById(R.id.btn_start);
btn_stop=(Button) findViewById(R.id.btn_stop);
btn_start.setOnClickListener(this);
btn_stop.setOnClickListener(this);
intent=new Intent(MainActivity.this, MyService.class);
//接收器的动态注册,Action必须与Service中的Action一致
registerReceiver(br, new IntentFilter("ACTION_MY"));
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_start:
startService(intent);
break;
case R.id.btn_stop:
stopService(intent);
break;
}
}
@Override
protected void onDestroy() {
//取接收器的消注册
unregisterReceiver(br);
super.onDestroy();
}
}

(3)注册Service,而BroadcastReceiver就不用再注册了

(4)运行效果:

即一个计时更新主页面的功能

Android Service和广播的更多相关文章

  1. Android -- service 利用广播调用服务的方法

    1. 实现原理,在Service里面注册一个广播接收者, 想要调用的时候app发送出广播, 后台的service里面的广播接收者接收到广播,并调用service里面的方法. 2. 示例代码 MainA ...

  2. android service 的各种用法(IPC、AIDL)

    http://my.oschina.net/mopidick/blog/132325 最近在学android service,感觉终于把service的各种使用场景和用到的技术整理得比较明白了,受益颇 ...

  3. Android之旅---广播(BroadCast)

    什么是广播 在Android中,Broadcast是一种广泛运用的在应用程序之间传输信息的机制.我们拿广播电台来做个比方.我们平常使用收音机收音是这样的:许许多多不同的广播电台通过特定的频率来发送他们 ...

  4. Android中的广播

    Android中的广播 广播接受器,可以比喻成收音机.而广播则可以看成电台. Android系统内部相当于已经有一个电台 定义了好多的广播事件,比如外拨电话 短信到来 sd卡状态 电池电量变化... ...

  5. 【Android】详解Android Service

    目录结构: contents structure [+] Service简单概述 Service在清单文件中的声明 Service启动服务 Service绑定服务 扩展Binder类 使用Messen ...

  6. 浅谈android Service和BroadCastReceiver

    1.题记 Android中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序. 广播接收者(BroadcastRece ...

  7. Android Service总结05 之IntentService

    Android Service总结05 之IntentService   版本 版本说明 发布时间 发布人 V1.0 添加了IntentService的介绍和示例 2013-03-17 Skywang ...

  8. Android Service总结04 之被绑定的服务 -- Bound Service

    Android Service总结04 之被绑定的服务 -- Bound Service 版本 版本说明 发布时间 发布人 V1.0 添加了Service的介绍和示例 2013-03-17 Skywa ...

  9. Android Service总结02 service介绍

    Android Service总结02 service介绍 版本 版本说明 发布时间 发布人 V1.0 介绍了Service的种类,常用API,生命周期等内容. 2013-03-16 Skywang ...

随机推荐

  1. jQuery对象和DOM对象的互相转换【 转】

    jQuery对象转换为dom对象 只有jQuery对象才能调用jQuery类库的各种函数,同样有些dom对象的属性和方法在jQuery上也是无法调用的,不过基本上jQuery类库提供的函数包含了所有的 ...

  2. js IDE WebStorm 注册码

    webStorm : UserName:William ===== LICENSE BEGIN ===== 45550-12042010 00001SzFN0n1bPII7FnAxnt0DDOPJA  ...

  3. phonegap ios插件开发及无限后台运行解决

    1.首先开发插件:因为我的项目前需要所以要做(根据情况) 在项目的plugins文件中新建obj c文件.如 Demo,此时会产生出Demo.h和Demo.m两个文件. .h文件主要就是定义一些方法, ...

  4. div+css布局细节问题

    cursor: pointer;在chrome里支持,hand不支持

  5. iOS VideoToolbox硬编H.265(HEVC)H.264(AVC):4 同步编码

    本文档描述Video Toolbox实现同步编码的办法. Video Toolbox在头文件描述了编码方式为异步,实际开发中也确实为异步. This function may be called as ...

  6. WPF 多线程处理(3)

    WPF 多线程处理(1) WPF 多线程处理(2) WPF 多线程处理(3) WPF 多线程处理(4) WPF 多线程处理(5) WPF 多线程处理(6) 首先我们需要几个属性来保存取得的数据,因为在 ...

  7. 文本编辑器 markdown

    http://www.cnblogs.com/youxia/p/linux014.html markdown对数学公式的支持http://www.linuxidc.com/Linux/2014-08/ ...

  8. IntelliJ IDEA创建项目技巧(转)

    转自:http://www.myext.cn/webkf/a_2539.html IntelliJ IDEA创建项目技巧 来源:网络    编辑:admin intellij idea教程 首先我要说 ...

  9. 剑指offer--面试题11

    题目:求数值的整数次方,不考虑大数值情况 即实现函数:double Power(double base, int exponent) 自己所写代码如下: #include "stdafx.h ...

  10. 2014 Multi-University Training Contest 3

    官方解题报告http://blog.sina.com.cn/s/blog_a19ad7a10102uyiq.html Wow! Such Sequence! http://acm.hdu.edu.cn ...