zoukankan      html  css  js  c++  java
  • android编写Service入门

    android SDK提供了Service,用于类似*nix守护进程或者windows的服务。

    Service有两种类型:

    1. 本地服务(Local Service):用于应用程序内部
    2. 远程服务(Remote Sercie):用于android系统内部的应用程序之间

          前者用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好。

    后者可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。

    编写不需和Activity交互的本地服务示例

          本地服务编写比较简单。首先,要创建一个Service类,该类继承android的Service类。这里写了一个计数服务的类,每秒钟为计数器加一。在服务类的内部,还创建了一个线程,用于实现后台执行上述业务逻辑。

    Service类:

    [java] view plaincopy
    1. package com.test;  
    2.   
    3. import android.app.Service;  
    4. import android.content.Intent;  
    5. import android.os.IBinder;  
    6. import android.util.Log;  
    7.   
    8. public class CountService extends Service {  
    9.     public static final String TAG = "CountService";  
    10.     private boolean threadDisable;  
    11.     private int count ;  
    12.       
    13.     @Override  
    14.     public IBinder onBind(Intent intent) {  
    15.         // TODO Auto-generated method stub  
    16.         return null;  
    17.     }  
    18.   
    19.     @Override  
    20.     public void onCreate() {  
    21.         // TODO Auto-generated method stub  
    22.         super.onCreate();  
    23.         new Thread(new Runnable(){  
    24.             @Override  
    25.             public void run() {  
    26.                 // TODO Auto-generated method stub  
    27.                 while(!threadDisable){  
    28.                     try {  
    29.                         Thread.sleep(1000);  
    30.                     } catch (InterruptedException e) {  
    31.                         // TODO Auto-generated catch block  
    32.                         e.printStackTrace();  
    33.                     }  
    34.                     count++;  
    35.                     Log.v(TAG , "Count="+count);  
    36.                 }  
    37.             }  
    38.         }).start();  
    39.     }  
    40.   
    41.     @Override  
    42.     public void onDestroy() {  
    43.         // TODO Auto-generated method stub  
    44.         super.onDestroy();  
    45.         threadDisable = true;  
    46.         Log.v(TAG , "onDestroy");  
    47.     }  
    48.       
    49.     public int getCount(){  
    50.         return count;  
    51.     }  
    52.       
    53. }  
    需要将该服务注册到配置文件AndroidManifest.xml中,否则无法找到:

    [html] view plaincopy
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     package="com.test"  
    4.     android:versionCode="1"  
    5.     android:versionName="1.0" >  
    6.   
    7.     <uses-sdk android:minSdkVersion="15" />  
    8.   
    9.     <application  
    10.         android:icon="@drawable/ic_launcher"  
    11.         android:label="@string/app_name" >  
    12.         <activity  
    13.             android:name=".LocalServiceDemoActivity"  
    14.             android:label="@string/app_name" >  
    15.             <intent-filter>  
    16.                 <action android:name="android.intent.action.MAIN" />  
    17.   
    18.                 <category android:name="android.intent.category.LAUNCHER" />  
    19.             </intent-filter>  
    20.         </activity>  
    21.         <span style="color:#000000;"><service android:name="CountService"/></span>  
    22.     </application>  
    23. </manifest>  
    在Activity中启动和关闭本地服务:

    [java] view plaincopy
    1. package com.test;  
    2.   
    3. import android.app.Activity;  
    4. import android.content.Intent;  
    5. import android.os.Bundle;  
    6.   
    7. public class LocalServiceDemoActivity extends Activity {  
    8.     /** Called when the activity is first created. */  
    9.     @Override  
    10.     public void onCreate(Bundle savedInstanceState) {  
    11.         super.onCreate(savedInstanceState);  
    12.         setContentView(R.layout.main);  
    13.           
    14.         startService(new Intent(this , CountService.class));  
    15.     }  
    16.   
    17.     @Override  
    18.     protected void onDestroy() {  
    19.         // TODO Auto-generated method stub  
    20.         super.onDestroy();  
    21.         stopService(new Intent(this , CountService.class));  
    22.     }  
    23.       
    24. }  
    可通过日志查看到后台线程打印的计数内容。

    ==================================================

    编写本地服务和Activity交互的示例

          上面的示例是通过startService和stopService启动关闭服务的。适用于服务和activity之间没有交互调用的情况。如果之间需要传递参数或者方法调用。需要使用bind和unbind方法。

          具体做法是,服务类需要增加接口,比如ICountService,另外,服务类需要有一个内部类,这样可以方便访问外部类的封装数据,这个内部类需要继承Binder类并实现ICountService接口。还有,就是要实现Service的onBind方法,不能只传回一个null了。

    这是新建立的接口代码:

    [java] view plaincopy
    1. package com.test;  
    2.   
    3. public interface ICountService {  
    4.     public abstract int getCount();  
    5. }  

    修改后的CountService代码:
    [java] view plaincopy
    1. package com.test;  
    2.   
    3. import android.app.Service;  
    4. import android.content.Intent;  
    5. import android.os.Binder;  
    6. import android.os.IBinder;  
    7. import android.util.Log;  
    8.   
    9. public class CountService extends Service {  
    10.     public static final String TAG = "CountService";  
    11.     private boolean threadDisable;  
    12.     private int count ;  
    13.       
    14.     private ServiceBinder serviceBinder = new ServiceBinder();  
    15.       
    16.     public class ServiceBinder extends Binder implements ICountService{  
    17.         @Override  
    18.         public int getCount() {  
    19.             // TODO Auto-generated method stub  
    20.             return count;  
    21.         }  
    22.     }  
    23.       
    24.     @Override  
    25.     public IBinder onBind(Intent intent) {  
    26.         // TODO Auto-generated method stub  
    27.         return serviceBinder;  
    28.     }  
    29.   
    30.     @Override  
    31.     public void onCreate() {  
    32.         // TODO Auto-generated method stub  
    33.         super.onCreate();  
    34.         new Thread(new Runnable(){  
    35.             @Override  
    36.             public void run() {  
    37.                 // TODO Auto-generated method stub  
    38.                 while(!threadDisable){  
    39.                     try {  
    40.                         Thread.sleep(1000);  
    41.                     } catch (InterruptedException e) {  
    42.                         // TODO Auto-generated catch block  
    43.                         e.printStackTrace();  
    44.                     }  
    45.                     count++;  
    46.                     Log.v(TAG , "Count="+count);  
    47.                 }  
    48.             }  
    49.         }).start();  
    50.     }  
    51.   
    52.     @Override  
    53.     public void onDestroy() {  
    54.         // TODO Auto-generated method stub  
    55.         super.onDestroy();  
    56.         threadDisable = true;  
    57.         Log.v(TAG , "onDestroy");  
    58.     }  
    59.       
    60.     public int getCount(){  
    61.         return count;  
    62.     }  
    63.       
    64. }  
    服务的注册也要做改动,AndroidManifest.xml文件:

    [html] view plaincopy
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     package="com.test"  
    4.     android:versionCode="1"  
    5.     android:versionName="1.0" >  
    6.   
    7.     <uses-sdk android:minSdkVersion="15" />  
    8.   
    9.     <application  
    10.         android:icon="@drawable/ic_launcher"  
    11.         android:label="@string/app_name" >  
    12.         <activity  
    13.             android:name=".LocalServiceDemoActivity"  
    14.             android:label="@string/app_name" >  
    15.             <intent-filter>  
    16.                 <action android:name="android.intent.action.MAIN" />  
    17.                 <category android:name="android.intent.category.LAUNCHER" />  
    18.             </intent-filter>  
    19.         </activity>  
    20.         <!-- <service android:name="CountService"/> -->    
    21.         <span style="color:#000000;"><service android:name="CountService">  
    22.             <intent-filter>  
    23.                 <action android:name="com.test.CountService"  />  
    24.             </intent-filter>  
    25.         </service></span>  
    26.     </application>  
    27. </manifest>  
    Acitity代码不再通过startSerivce和stopService启动关闭服务,另外,需要通过ServiceConnection的内部类实现来连接Service和Activity。

    [java] view plaincopy
    1. package com.test;  
    2.   
    3. import android.app.Activity;  
    4. import android.content.ComponentName;  
    5. import android.content.Intent;  
    6. import android.content.ServiceConnection;  
    7. import android.os.Bundle;  
    8. import android.os.IBinder;  
    9. import android.util.Log;  
    10.   
    11. public class LocalServiceDemoActivity extends Activity {  
    12.     private ICountService countService;  
    13.       
    14.     private ServiceConnection serviceConnection = new ServiceConnection(){  
    15.         @Override  
    16.         public void onServiceConnected(ComponentName name, IBinder service) {  
    17.             // TODO Auto-generated method stub  
    18.             countService = (ICountService)service;  
    19.             Log.v(CountService.TAG , "on service connected,count is:"+  
    20.             countService.getCount());  
    21.         }  
    22.         @Override  
    23.         public void onServiceDisconnected(ComponentName name) {  
    24.             // TODO Auto-generated method stub  
    25.             countService = null ;  
    26.         }  
    27.     };  
    28.       
    29.     /** Called when the activity is first created. */  
    30.     @Override  
    31.     public void onCreate(Bundle savedInstanceState) {  
    32.         super.onCreate(savedInstanceState);  
    33.         setContentView(R.layout.main);  
    34.           
    35.         //startService(new Intent(this , CountService.class));  
    36.         this.bindService(new Intent("com.test.CountService"),   
    37.                 this.serviceConnection, BIND_AUTO_CREATE);  
    38.     }  
    39.   
    40.     @Override  
    41.     protected void onDestroy() {  
    42.         // TODO Auto-generated method stub  
    43.         super.onDestroy();  
    44.         Log.v(CountService.TAG , "last onDestroy,count is:"+  
    45.                 countService.getCount());  
    46.         //stopService(new Intent(this , CountService.class));  
    47.         this.unbindService(serviceConnection);  
    48.     }  
    49.       
    50. }  

    编写传递基本型数据的远程服务

    上面的示例,可以扩展为,让其他应用程序复用该服务。这样的服务叫远程(remote)服务,实际上是进程间通信(RPC)。

    这时需要使用android接口描述语言(AIDL)来定义远程服务的接口,而不是上述那样简单的java接口。扩展名为aidl而不是java。可用上面的ICountService改动而成ICountSerivde.aidl,eclipse会自动生成相关的java文件。

    [java] view plaincopy
    1. package com.test;  
    2.   
    3. interface ICountService {  
    4.     int getCount();  
    5. }  

    编写服务(Service)类,稍有差别,主要在binder是通过远程获得的,需要通过桩(Stub)来获取。桩对象是远程对象的本地代理

    [java] view plaincopy
    1. package com.test;  
    2.   
    3. import android.app.Service;  
    4. import android.content.Intent;  
    5. import android.os.IBinder;  
    6. import android.os.RemoteException;  
    7. import android.util.Log;  
    8.   
    9. public class CountService extends Service {  
    10.     public static final String TAG = "CountService";  
    11.     private boolean threadDisable;  
    12.     private int count ;  
    13.       
    14.     private ICountService.Stub serviceBinder = new ICountService.Stub(){  
    15.         @Override  
    16.         public int getCount() throws RemoteException {  
    17.             // TODO Auto-generated method stub  
    18.             return count;  
    19.         }  
    20.           
    21.     };  
    22.       
    23.     @Override  
    24.     public IBinder onBind(Intent intent) {  
    25.         // TODO Auto-generated method stub  
    26.         return serviceBinder;  
    27.     }  
    28.   
    29.     @Override  
    30.     public void onCreate() {  
    31.         // TODO Auto-generated method stub  
    32.         super.onCreate();  
    33.         new Thread(new Runnable(){  
    34.             @Override  
    35.             public void run() {  
    36.                 // TODO Auto-generated method stub  
    37.                 while(!threadDisable){  
    38.                     try {  
    39.                         Thread.sleep(1000);  
    40.                     } catch (InterruptedException e) {  
    41.                         // TODO Auto-generated catch block  
    42.                         e.printStackTrace();  
    43.                     }  
    44.                     count++;  
    45.                     Log.v(TAG , "Count="+count);  
    46.                 }  
    47.             }  
    48.         }).start();  
    49.     }  
    50.   
    51.     @Override  
    52.     public void onDestroy() {  
    53.         // TODO Auto-generated method stub  
    54.         super.onDestroy();  
    55.         threadDisable = true;  
    56.         Log.v(TAG , "onDestroy");  
    57.     }  
    58.       
    59. }  

    配置文件AndroidManifest.xml和上面的类似,没有区别。

    在Activity中使用服务的差别不大,只需要对ServiceConnection中的调用远程服务的方法时,要捕获异常。

    [java] view plaincopy
    1. package com.test;  
    2.   
    3. import android.app.Activity;  
    4. import android.content.ComponentName;  
    5. import android.content.Intent;  
    6. import android.content.ServiceConnection;  
    7. import android.os.Bundle;  
    8. import android.os.IBinder;  
    9. import android.os.RemoteException;  
    10. import android.util.Log;  
    11.   
    12. public class LocalServiceDemoActivity extends Activity {  
    13.     private ICountService countService;  
    14.       
    15.     private ServiceConnection serviceConnection = new ServiceConnection(){  
    16.         @Override  
    17.         public void onServiceConnected(ComponentName name, IBinder service) {  
    18.             // TODO Auto-generated method stub  
    19.             countService = (ICountService)service;  
    20.             try {  
    21.                 Log.v(CountService.TAG , "on service connected,count is:"+  
    22.                 countService.getCount());  
    23.             } catch (RemoteException e) {  
    24.                 // TODO Auto-generated catch block  
    25.                 throw new RuntimeException(e);  
    26.             }  
    27.         }  
    28.         @Override  
    29.         public void onServiceDisconnected(ComponentName name) {  
    30.             // TODO Auto-generated method stub  
    31.             countService = null ;  
    32.         }  
    33.     };  
    34.       
    35.     /** Called when the activity is first created. */  
    36.     @Override  
    37.     public void onCreate(Bundle savedInstanceState) {  
    38.         super.onCreate(savedInstanceState);  
    39.         setContentView(R.layout.main);  
    40.           
    41.         //startService(new Intent(this , CountService.class));  
    42.         this.bindService(new Intent("com.test.CountService"),   
    43.                 this.serviceConnection, BIND_AUTO_CREATE);  
    44.     }  
    45.   
    46.     @Override  
    47.     protected void onDestroy() {  
    48.         // TODO Auto-generated method stub  
    49.         super.onDestroy();  
    50.         try {  
    51.             Log.v(CountService.TAG , "last onDestroy,count is:"+  
    52.                     countService.getCount());  
    53.         } catch (RemoteException e) {  
    54.             // TODO Auto-generated catch block  
    55.             e.printStackTrace();  
    56.         }  
    57.         //stopService(new Intent(this , CountService.class));  
    58.         this.unbindService(serviceConnection);  
    59.     }  
    60.       
    61. }  

    这样就可以在同一个应用程序中使用远程服务的方式和自己定义的服务交互了。

    如果是另外的应用程序使用远程服务,需要做的是复制上面的aidl文件和相应的包构到应用程序中,其他调用等都一样。

    编写传递复杂数据类型的远程服务

    服务的生命周期

  • 相关阅读:
    linux
    查看字符的编码数字
    各种语系的unicode对应以及local编码方式
    Unicode字符集,各个语言的区间
    深入理解Python的字符编码
    php 快排
    归并排序
    检测到在集成的托管管道模式下不适用的 ASP.NET 设置的解决方法
    分布式缓存MemcacheHelper
    单例模式
  • 原文地址:https://www.cnblogs.com/walccott/p/4957020.html
Copyright © 2011-2022 走看看