• 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.

  • 相关阅读:
    静态变量一定要先声明后赋值
    建议3 三元操作的类型必一致
    IDEA 创建 Maven web项目注意事项
    js不同类型作比较
    exception中return方法
    exception 打印出异常栈踪迹
    spring controller使用了@ResponseBody却返回xml
    springboot中的406(Not Acceptable)错误
    把本地建好的项目提交到git上
    java基础---------方法和方法重载
  • 原文地址:https://www.cnblogs.com/androidsj/p/3972420.html
Copyright © 2020-2023  润新知