7、四大组件之二-Service高级

一、Native Service

1>什么是Native Service

使用JNI编写,在系统启动完成之前启动的系统级服务。

2>哪些服务是Native Service

ACCESSIBILITY_SERVICE

ACCOUNT_SERVICE

ACTIVITY_SERVICE

ALARM_SERVICE

AUDIO_SERVICE

CLIPBOARD_SERVICE

CONNECTIVITY_SERVICE

DEVICE_POLICY_SERVICE

DOWNLOAD_SERVICE

DROPBOX_SERVICE

INPUT_METHOD_SERVICE

KEYGUARD_SERVICE

LAYOUT_INFLATER_SERVICE

LOCATION_SERVICE

NOTIFICATION_SERVICE

POWER_SERVICE

SEARCH_SERVICE

SENSOR_SERVICE

STORAGE_SERVICE

TELEPHONY_SERVICE

UI_MODE_SERVICE

USB_SERVICE

VIBRATOR_SERVICE

WALLPAPER_SERVICE

WIFI_SERVICE

WINDOW_SERVICE

3>如何使用(示例)

 1 //A. 怎么才能从资源文件中创建View呢?
 2 ////////////////////////////////////////////
 3 //调用LAYOUT_INFLATER_SERVICE,从资源中创建layout.
 4 ////////////////////////////////////////////
 5 LayoutInflater inflater= (LayoutInflater)context.getSystemService(
 6      Context.LAYOUT_INFLATER_SERVICE);
 7 View v = inflater.inflate(R.layout.list_item, null);
 8 
 9 //B. 手机底座(Dock)是一种外设,一般分为Car Dock和Desk Dock
10 //
11 //当插入手机底座时,我们可能需要带给用户不同的体验。
12 //如:当插入Car Dock时,用户可能是将手机放在汽车的手机底座上,并很有可能正在开车途中。
13 //此时我们应将某些界面转入驾驶模式,如精简用户界面、加大图标及文字的显示等,以方便用户操作。
14 //
15 //那么,我们应当如何了解手机底座的插入状态呢?
16 //
17 ////////////////////////////////////////////
18 //使用UI_MODE_SERVICE查看当前手机的底座状态
19 ////////////////////////////////////////////
20 UiModeManager uiModeManager = (UiModeManager)getSystemService(Context.UI_MODE_SERVICE);
21 switch(uiModeManager.getCurrentModeType())
22 case Configuration.UI_MODE_TYPE_NORMAL:
23   dockState.setText("no dock");
24   break;
25 case Configuration.UI_MODE_TYPE_CAR:
26   dockState.setText("car dock mode");
27   break;
28 case Configuration.UI_MODE_TYPE_DESK:
29 {
30   dockState.setText("desk dock mode");
31   break;
32 }

4>Native Service的创建过程 (在系统启动完成之前)

(1) 获取Default Service Manager

(2) 创建NativeService并加入ServiceManager

(3) 启动线程池,开始处理Application传入的请求

二、Bound Service

1>什么是Bound Service

2>怎么使用

【Service】

 1 //示例3.3.2
 2 //BinderService.java
 3 public class BinderService extends Service {
 4   
 5   public interface ICallback{
 6     //在收到Message时被调用
 7     public void onMessage(String msg);
 8   }
 9   private Set<ICallback> mCallbackList = new HashSet<ICallback>();
10   
11   public class ServiceBinder extends Binder{
12     //将收到的Message通知所有的Callback
13     public void sendMessage(String msg){
14        for (ICallback c : mCallbackList){
15          c.onMessage(msg);
16        }
17     }
18     
19     //将Callback添加到链表
20     public void RegisterCallback(ICallback callback){
21        mCallbackList.add(callback);
22     }
23     
24     //将Callback从链表中删除
25     public void UnregisterCallback(ICallback callback){
26        mCallbackList.remove(callback);
27     }
28   }
29   private ServiceBinder mBinder = new ServiceBinder();
30   @Override
31   public IBinder onBind(Intent arg0) {
32     return mBinder;
33   }
34 }

(1)创建Service并在AndroidManifest.xml中添加相关信息

(2)继承Binder类

(3)在OnBind()函数中返回Binder对象

 

【Client (如Activity)】

 1 //示例3.3.3
 2 //ServiceTestActivity.java
 3 
 4 public class ServiceTestActivity extends Activity{
 5   private ServiceBinder mService = null;
 6   
 7   //实现Service的Callback, 当收到Message时, 使用Toast将其显示出来
 8   private ICallback    mCallback = new ICallback(){
 9     @Override
10     public void onMessage(String msg) {
11        Toast.makeText(getApplication(), "Get message: " + msg, Toast.LENGTH_LONG).show();
12     }
13   };
14   
15   //在OnCreate时BindService
16   //但需注意的时,此时Service还没有被绑定,而需要等到onServiceConnected执行时才能使用。
17     @Override
18     public void onCreate(Bundle savedInstanceState) {
19         super.onCreate(savedInstanceState);
20         bindService(new Intent(this, BinderService.class), mConnection, BIND_AUTO_CREATE);
21     }
22     
23     //在onDestroy时unbindService,mService不应再被使用
24     @Override
25   protected void onDestroy() {
26     if (mService != null){
27        mService.UnregisterCallback(mCallback);
28        unbindService(mConnection);
29     }
30     
31     super.onDestroy();
32   }
33 
34   private ServiceConnection mConnection = new ServiceConnection() {
36     //Service绑定完成
37         @Override
38         public void onServiceConnected(ComponentName className,
39                 IBinder service) {
40          mService = (ServiceBinder) service;
41          mService.RegisterCallback(mCallback);
42          mService.sendMessage("Service Connected!");
43         }
45         //Service已断开
46         @Override
47         public void onServiceDisconnected(ComponentName className) {
48          mService = null;
49         }
50     };
51 }

(1)调用BindSerive

(2)实现ServiceConnection

(3)在onServiceConnected中保存由Service提供的Binder对象

 

3>如何与Client交互

(1)编写ICallback接口

(2)在Service的Binder类中实现RegisterCallback和UnregisterCallback

(3)在Client中调用RegisterCallback

4>分类

【Local Service】

只能被当前进程调用 参考:示例3.3.2, 3.3.3

【Remote Service】

可以被其它进程调用的Service, 可用于进程间的数据共享。

 1>Service

(1)   创建AIDL文件

 1 (2)    //示例3.3.4
 2 (3)    //IRemoteService.aidl 4 (5)    package com.demo.service; 6 (7)    /*
 7 (8)     * 在AIDL文件中只能使用一下类型的数据:
 8 (9)     * 
 9 (10)     * 基础类型(int, long, boolean等)
10 (11)     * String
11 (12)     * CharSequence
12 (13)     * List
13 (14)     * Map
14 (15)     */
15 (16)    interface IRemoteService {
16 (17)        int getVersion();(18)    }

(2) 在Service中实现AIDL中的接口,并返回给Client

 1 //示例3.3.5
 2 //RemoteService.java
 3 public class RemoteService extends Service {
 4   private static final int VERSION = 1492;
 5   public class RemoteBinder extends IRemoteService.Stub{
 6     @Override
 7     public int getVersion() throws RemoteException {
 8        return VERSION;
 9     }   
10   }
11   private RemoteBinder mBinder = new RemoteBinder();
12   @Override
13   public IBinder onBind(Intent intent) {
14     return mBinder;
15   }
16 }

(3) 在AndroidManifest中添加相关信息

1 //示例3.3.6
2 <serviceandroid:name="RemoteService">
3   <intent-filter>
4      <actionandroid:name="com.demo.service.action.REMOTE_SERVICE"/>
5   </intent-filter>
6 </service>

2>Client

(1) 复制AIDL文件至相应的目录

(2) 编译项目,Eclipse会自动生成相关的服务接口类

(3) 调用bindService绑定服务

 1 //示例3.3.7
 2 //注意:这里应该使用远程服务的action,而不能再直接用class
 3 bindService(newIntent("com.demo.service.action.REMOTE_SERVICE"), mConnection,BIND_AUTO_CREATE);
 4 //ServiceConnection
 5   private ServiceConnection mConnection = new ServiceConnection() {
 6     @Override
 7     public void onServiceConnected(ComponentName name, IBinder service) {
 8         //注意这里应该使用asInterface方法进行转换
 9        mService = IRemoteService.Stub.asInterface(service);//(IRemoteService)service;
10        Log.e("Alfred", "onServiceConnected" + mService);
11        try {
12          Log.e("Alfred", "version: " + mService.getVersion());
13        } catch (RemoteException e) {
14          e.printStackTrace();
15        }
16     }
17     @Override
18     public void onServiceDisconnected(ComponentName name) {
19        mService = null;
20     }
21 };

三、什么时候使用Intent Service, 什么时候使用Bound Service

    通常,在只需要Service执行一个简单的请求,只需要传递参数,而不在乎返回值、无需和Service有交互操作时,我们使用

IntentService。

    若我们需要知道Service的处理结果,或者和Service之间有交互操作(一般通过Callback实现)时,我们使用Bound  Service.

原文地址:https://www.cnblogs.com/androidsj/p/3972420.html