zoukankan      html  css  js  c++  java
  • android学习日记19--四大组件之Services(服务)

      一个Android应用主要由四个基本组件组成,Android四大基本组件分别是Activity,Content Provider内容提供者,Service服务,BroadcastReceiver广播接收器。
    其中Activity和Content Provider在前面都有介绍过。这里主要讲讲Service服务和BroadcastReceiver广播接收器。


    一、Services(服务)

     

    1、简述
      Services(服务)简单来说就是剥夺界面的Activity。它和Activity很多概念都是相似的,都是封装有一个完整的功能逻辑实现。
    Services是运行在后台的一段代码,它可以运行在它自己的进程,也可以运行在其他应用程序进程的上下文(context)里面,
    其它的组件可以绑定到一个服务(Service)上面,通过远程过程调用(RPC)来调用这个方法。常见的Services如后台音乐播放,
    后台计算数据。

     

    2、运行原理
      有两种运行方式,原理如下:
      a、使用Context.startService()来启动一个Service,从而可以在后台调用Service。同时,系统也将保持这个Service一直执行,
         直到这个Service运行结束。
      b、使用Context.bindService()方法,连接到一个Service上(如果这个Service还没有运行将启动它)。当连接到一个Service之后,
           我们还可以Service提供的接口与它进行通讯。

     

    3、生命周期
      官方生命周期的图示:

      

      a、startService后,即使调用startService的进程结束了,Service仍然还存在,直到有进程调用stopService,或者Service自己自杀(stopSelf())。
      b、bindService后,Service就和调用bindService的进程同生共死了,也就是说当调用bindService的进程死了,那么它bind的Service也要跟着被结束,
         当然期间也可以调用unbindservice让 Service结束。
      c、两种方式混合使用时,比如说你startService了,我bindService了,那么只有你stopService了而且我也unbindservice了,这个Service才会被结束。

     

    4、使用步骤
      a、继承service类(位于android.app包下,一般用它的子类IntentService)

      b、AndroidManifast.xml配置清单文件中<application>节点里对服务进行配置

        <service name=".SMSService"/>
      c、服务不能自己运行,需要通过Contex.startService()或Contex.bindService()启动服务

      通过startService()方法启动的服务于调用者没有关系,即使调用者关闭了,服务仍然运行想停止服务要调用Context.stopService(),
    此时系统会调用onDestory(),使用此方法启动时,服务首次启动系统先调用服务的onCreate()-->onStart(),如果服务已经启动再次调用只会触发onStart()方法
    使用bindService()启动的服务与调用者绑定,只要调用者关闭服务就终止,使用此方法启动时,服务首次启动系统先调用服务的onCreate()-->onBind(),
    如果服务已经启动再次调用不会再触发这2个方法,调用者退出时系统会调用服务的onUnbind()-->onDestory(),想主动解除绑定可使用Contex.unbindService(),
    系统依次调用onUnbind()-->onDestory();

      区别使用 startService()还是bindService()就要看是否要和调用者进行通信,由于startService()和访问者不存在太多联系,所有有进行通信的要用bindService()。

    通过Service提供IBinder OnBind(Intent intent) 返回要通信的数据,在OnServiceConnected()方法 返回该Binder给调用者。

    5、运行实例

      运用两种启动Service服务写个后台播放音乐的例子

    MyServices主要代码:

     1 private static final String TAG = "MyService";  
     2     MediaPlayer player;  
     3       
     4     @Override  
     5     public IBinder onBind(Intent intent) {  
     6         return null;  
     7     }  
     8       
     9     @Override  
    10     public void onCreate() {  
    11         Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();  
    12         Log.v(TAG, "onCreate");  
    13           
    14         player = MediaPlayer.create(this, R.raw.ten_year);//运行例子是,需要替换具体音乐的名称  
    15         player.setLooping(false); // Set looping  
    16     }  
    17   
    18     @Override  
    19     public void onDestroy() {  
    20         Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();  
    21         Log.v(TAG, "onDestroy");  
    22         player.stop();  
    23     }  
    24       
    25     @Override  
    26     public void onStart(Intent intent, int startid) {  
    27         Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();  
    28         Log.v(TAG, "onStart");  
    29         player.start();  
    30     }

    MyBindService主要代码:

     1 private static final String TAG = "MyBindService";  
     2     MediaPlayer player = null;  
     3     MyBinder mybinder = new MyBinder();
     4     
     5     class MyBinder extends Binder{//需要新建个内部的Binder类
     6         
     7         public MyBindService getService(){
     8             return MyBindService.this;
     9         }
    10     }
    11     
    12     @Override  
    13     public IBinder onBind(Intent intent) {  
    14         return mybinder;  
    15     }  
    16       
    17     @Override  
    18     public void onCreate() {  
    19         Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();  
    20         Log.v(TAG, "onCreate");  
    21         player = MediaPlayer.create(this, R.raw.ten_year);//运行例子是,需要替换音乐的名称  
    22         player.setLooping(false); // Set looping   
    23          
    24     }  
    25     
    26     public void playMusic() {
    27         
    28         player.start(); 
    29         Log.v(TAG, "playMusic");  
    30     }
    31   
    32     @Override  
    33     public void onDestroy() {  
    34         Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();  
    35         Log.v(TAG, "onDestroy");  
    36         player.stop();  
    37     }  
    38       
    39     @Override  
    40     public void onStart(Intent intent, int startid) {  
    41         Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();  
    42         Log.v(TAG, "onStart");  
    43          
    44     }

     

    Activity注册按钮事件,调用Service服务:

     1 ServiceConnection conn=new ServiceConnection() {
     2         
     3         @Override
     4         public void onServiceDisconnected(ComponentName arg0) {
     5             // TODO Auto-generated method stub
     6             
     7         }
     8         
     9         @Override
    10         public void onServiceConnected(ComponentName arg0, IBinder binder) {
    11             // TODO Auto-generated method stub
    12             MyBinder mBinder = (MyBinder) binder;
    13             MyBindService mService = mBinder.getService();//取到自己的Service
    14             mService.playMusic(); // 调用服务要执行的方法
    15         }
    16     };
    17 
    18       
    19       public void onClick(View src) {  
    20         switch (src.getId()) {  
    21         case R.id.btn_start:  
    22             Log.v(TAG, "onClick: start srvice");  
    23             startService(new Intent(this, MyService.class));         
    24             break;  
    25         case R.id.btn_stop:  
    26             Log.v(TAG, "onClick: stop srvice");  
    27             stopService(new Intent(this, MyService.class));            
    28             break; 
    29         case R.id.btn_bind: 
    30             Log.v(TAG, "onClick: bind srvice");
    31             bindService(new Intent(MainActivity.this,MyBindService.class), conn,BIND_AUTO_CREATE);                
    32             break;  
    33         case R.id.btn_unbind:                
    34             if (true) {
    35                 Log.v(TAG, "onClick: unbind srvice");
    36                 unbindService(conn);
    37                 flag = false;
    38             }                            
    39           break;
    40         }  
    41       }  

     

    注意:unbind()调用是要进行判断,没bind()后不能多次调用unbind(),否则会报异常:

    java.lang.IllegalArgumentException: Service not registered

    最后别忘了AndroidManifast.xml里声明服务:

            <service android:enabled="true" android:name=".MyService" /> 
            <service android:enabled="true" android:name=".MyBindService" />

    依次点击四个按钮打印的日志:

    03-22 07:19:44.116: V/ServicesDemo(18347): onClick: start srvice
    03-22 07:19:44.166: V/MyService(18347): onStart
    03-22 07:19:48.807: V/ServicesDemo(18347): onClick: stop srvice
    03-22 07:19:48.837: V/MyService(18347): onDestroy
    03-22 07:19:50.957: V/ServicesDemo(18347): onClick: bind srvice
    03-22 07:19:50.997: V/MyBindService(18347): onCreate
    03-22 07:19:51.067: V/MyBindService(18347): playMusic
    03-22 07:19:55.997: V/ServicesDemo(18347): onClick: unbind srvice
    03-22 07:19:56.097: V/MyBindService(18347): onDestroy

    这里可以同时start srvice和bind srvice,这时就有两个相同的服务,根据调用的不同时间,播放不同进度的音乐。

    调用系统服务getSystemService是Activity中的方法,根据传入的name来取得对应的服务对象,这些服务名称参数都是Context类中的常量:

    传入的Name 返回的对象 说明
      WINDOW_SERVICE WindowManager 管理打开的窗口程序
      LAYOUT_INFLATER_SERVICE LayoutInflater 取得xml里定义的view
      ACTIVITY_SERVICE ActivityManager 管理应用程序的系统状态
      POWER_SERVICE PowerManger 电源的服务
      ALARM_SERVICE AlarmManager 闹钟的服务
      NOTIFICATION_SERVICE NotificationManager 状态栏的服务
      KEYGUARD_SERVICE KeyguardManager 键盘锁的服务
      LOCATION_SERVICE LocationManager 位置的服务,如GPS
      SEARCH_SERVICE SearchManager 搜索的服务
      VEBRATOR_SERVICE Vebrator 手机震动的服务
      CONNECTIVITY_SERVICE Connectivity 网络连接的服务
      WIFI_SERVICE WifiManager Wi-Fi服务
      TELEPHONY_SERVICE TeleponyManager 电话服务

    BroadcastReceiver广播接收器放在下一篇介绍吧!

  • 相关阅读:
    自学mvc4.0 工作当中随笔(在view页面当中循环table,当遇到html标签怎么处理)
    安卓当中的线程和每秒刷一次
    通过后台代码访问前台js
    学习正则表达式记录
    net 当中动态给记事本当中插入值
    session,cookie 等区别
    vss 2.0框架与4.0框架的设置iis区别
    Javascript中char和int的互相转换的代码(转载)
    获得鼠标在页面上的坐标
    HTTP协议header头域
  • 原文地址:https://www.cnblogs.com/aiguozhe/p/3617215.html
Copyright © 2011-2022 走看看