首页 > 代码库 > Android Service和广播

Android Service和广播

前言:

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

 

 

一.Service的使用

ServiceAndroid系统的后台服务组件,没有用户界面,但可以长时间的运行,比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=0;     //继承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, 1000, 1000);     }     //停止定时器     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=0;     private int j=0;     //创建内部类,用于创建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, 1000,1000);     }     //停止计时     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", 0);                 int scale=intent.getIntExtra("scale", 100);                 tv.setText("当前电量:"+level*100/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=0;     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, 500,1000);     }     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", 0);             System.out.println(intent.getIntExtra("id", 0));             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和广播