Android Service和广播
前言:
我们都知道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和广播的更多相关文章
- Android -- service 利用广播调用服务的方法
1. 实现原理,在Service里面注册一个广播接收者, 想要调用的时候app发送出广播, 后台的service里面的广播接收者接收到广播,并调用service里面的方法. 2. 示例代码 MainA ...
- android service 的各种用法(IPC、AIDL)
http://my.oschina.net/mopidick/blog/132325 最近在学android service,感觉终于把service的各种使用场景和用到的技术整理得比较明白了,受益颇 ...
- Android之旅---广播(BroadCast)
什么是广播 在Android中,Broadcast是一种广泛运用的在应用程序之间传输信息的机制.我们拿广播电台来做个比方.我们平常使用收音机收音是这样的:许许多多不同的广播电台通过特定的频率来发送他们 ...
- Android中的广播
Android中的广播 广播接受器,可以比喻成收音机.而广播则可以看成电台. Android系统内部相当于已经有一个电台 定义了好多的广播事件,比如外拨电话 短信到来 sd卡状态 电池电量变化... ...
- 【Android】详解Android Service
目录结构: contents structure [+] Service简单概述 Service在清单文件中的声明 Service启动服务 Service绑定服务 扩展Binder类 使用Messen ...
- 浅谈android Service和BroadCastReceiver
1.题记 Android中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序. 广播接收者(BroadcastRece ...
- Android Service总结05 之IntentService
Android Service总结05 之IntentService 版本 版本说明 发布时间 发布人 V1.0 添加了IntentService的介绍和示例 2013-03-17 Skywang ...
- Android Service总结04 之被绑定的服务 -- Bound Service
Android Service总结04 之被绑定的服务 -- Bound Service 版本 版本说明 发布时间 发布人 V1.0 添加了Service的介绍和示例 2013-03-17 Skywa ...
- Android Service总结02 service介绍
Android Service总结02 service介绍 版本 版本说明 发布时间 发布人 V1.0 介绍了Service的种类,常用API,生命周期等内容. 2013-03-16 Skywang ...
随机推荐
- WPF 使用定时器
WPF 使用定时器:<ProgressBar Height="10" HorizontalAlignment="Left" Margin="28 ...
- Java集合的小抄
在尽可能短的篇幅里,将所有集合与并发集合的特征.实现方式.性能捋一遍.适合所有"精通Java",其实还不那么自信的人阅读. [转自:花钱的年华] 期望能不止用于面试时,平时选择数据 ...
- 【转载】MySQL 日志 undo | redo
本文是介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版 ...
- Fat-tree 胖树交换网络
胖树架构下,网络带宽不收敛 传统的树形网络拓扑中,带宽是逐层收敛的,树根处的网络带宽要远小于各个叶子处所有带宽的总和. 而胖树网络则更像是真实的树,越到树根,枝干越粗,即:从叶子到树根,网络带宽不收敛 ...
- Linq to XML 之XElement的Descendants方法的新发现
C#操作XML的方法有很多,但个人认为最方便的莫过于Linq to XML了,特别是XElement的Descendants方法是我最常用的一个方法. 这个方法可以根据节点名(Name)找到当前调用的 ...
- SharePoint 2010/SharePoint 2013 Custom Action: 基于Site Collection 滚动文字的通知.
应用场景: 有时候我们的站点需要在每个页面实现滚动文字的通知,怎么在不修改Master Page的情况下实现这个功能?我们可以使用Javascript 和 Custom Action 来实现. 创建一 ...
- VBS基础篇 - wscript 对象
一.wscript对象 描述:提供对 Windows 脚本宿主对象模型根对象的访问.详述:WScript 对象是 Windows 脚本宿主对象模型层次结构的根对象.它可在任何脚本文件中使用,不需要特定 ...
- python学习小结9:面向对象
面向对象技术 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类变量:类变量在整个实例化的对象中是公用的.类变量定义在类中且 ...
- SQL Server备份事务日志结尾(Tail)
原文:http://blog.csdn.net/tjvictor/article/details/5256906 事务日志结尾经常提交数据库未备份的事务日志内容.基本上,每一次你执行事务日志备份时 ...
- Jenkins入门-转
reference : http://www.cnblogs.com/itech/archive/2011/11/23/2260009.html 在网上貌似没有找到Jenkins的中文的太多的文档,有 ...