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广播接收器放在下一篇介绍吧!

  • 相关阅读:
    深入Android 【一】 —— 序及开篇
    Android中ContentProvider和ContentResolver使用入门
    深入Android 【六】 —— 界面构造
    The service cannot be activated because it does not support ASP.NET compatibility. ASP.NET compatibility is enabled for this application. Turn off ASP.NET compatibility mode in the web.config or add the AspNetCompatibilityRequirements attribute to the ser
    Dynamic Business代码片段总结
    对文件的BuildAction以content,resource两种方式的读取
    paraview 3.12.0 windows下编译成功 小记
    百度网盘PanDownload使用Aria2满速下载
    netdata的安装与使用
    用PS给证件照排版教程
  • 原文地址:https://www.cnblogs.com/aiguozhe/p/3617215.html
Copyright © 2011-2022 走看看