职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 1433|回复: 6

SystemServer Serivce 启动 与 获取 (addService ,checkService )

[复制链接]
jinchang 发表于 2011-7-28 10:04 | 显示全部楼层 |阅读模式
       在系统启动的时候,会做一系列初始化的工作包括service的创建。所以要了解系统中有多少种类的服务,每一类的服务都是如何实现的,这是一个最好的入口。这就直接从代码入手进行解析:
      转载请注明(http://ishelf.iteye.com/blog/1027886
      首先在SystemServer的run方法中,有如下代码

  
try {   
    Slog.i(TAG, "Input Method Service");   
    imm = new InputMethodManagerService(context, statusBar);   
    ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);   
} catch (Throwable e) {   
    Slog.e(TAG, "Failure starting Input Manager Service", e);   
}   
  
try {   
    Slog.i(TAG, "NetStat Service");   
    ServiceManager.addService("netstat", new NetStatService(context));   
} catch (Throwable e) {   
    Slog.e(TAG, "Failure starting NetStat Service", e);   
}   
  
try {   
    Slog.i(TAG, "NetworkManagement Service");   
    ServiceManager.addService(   
            Context.NETWORKMANAGEMENT_SERVICE, new NetworkManagementService(context));   
} catch (Throwable e) {   
    Slog.e(TAG, "Failure starting NetworkManagement Service", e);   
}  

            try {
                Slog.i(TAG, "Input Method Service");
                imm = new InputMethodManagerService(context, statusBar);
                ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
            } catch (Throwable e) {
                Slog.e(TAG, "Failure starting Input Manager Service", e);
            }

            try {
                Slog.i(TAG, "NetStat Service");
                ServiceManager.addService("netstat", new NetStatService(context));
            } catch (Throwable e) {
                Slog.e(TAG, "Failure starting NetStat Service", e);
            }

            try {
                Slog.i(TAG, "NetworkManagement Service");
                ServiceManager.addService(
                        Context.NETWORKMANAGEMENT_SERVICE, new NetworkManagementService(context));
            } catch (Throwable e) {
                Slog.e(TAG, "Failure starting NetworkManagement Service", e);
            }


       如上所示,这段代码是在启动bootanim(setprop("ctl.start","bootanim"))服务时通过系统命令启动的,主要功能就是启动常驻android的所有后台服务,例如T卡服务、包解析服务、wifi服务、蓝牙服务等等。在addService方法中第一个参数表示该服务的名称,第二个参数表示该服务的类(Ibinder的子类)。接下来的问题就是服务已经启动了,可是如何在其他的地方调用这些服务并作出相应的动作,例如在关机过程中要UnMount sd卡等。
      这里需要使用到ServiceManager类,先给出调用代码

  
final IBluetooth bluetooth =   
        IBluetooth.Stub.asInterface(ServiceManager.checkService(   
                BluetoothAdapter.BLUETOOTH_SERVICE));   
try {   
    bluetoothOff = bluetooth == null ||   
                   bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;   
    if (!bluetoothOff) {   
        bluetooth.disable(false);  // disable but don't persist new state   
    }   
} catch (RemoteException ex) {   
    bluetoothOff = true;   
}  

        final IBluetooth bluetooth =
                IBluetooth.Stub.asInterface(ServiceManager.checkService(
                        BluetoothAdapter.BLUETOOTH_SERVICE));
        try {
            bluetoothOff = bluetooth == null ||
                           bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
            if (!bluetoothOff) {
                bluetooth.disable(false);  // disable but don't persist new state
            }
        } catch (RemoteException ex) {
            bluetoothOff = true;
        }       方法checkService的参数就是addService中设置的对应service的名称,例如要获取蓝牙耳机的service,需要BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE,而对应的Ibinder类则是IBluetoothA2dp。









broken 发表于 2011-7-28 10:04 | 显示全部楼层
问一下楼主,如何手动启动一个自己写的服务呢?看了些代码都是用广播监听来开机启动的,我如何手动启动一个服务,难道要在activity里写一个intent?


已经来了吗 发表于 2011-7-28 10:04 | 显示全部楼层
busiying119
问一下楼主,如何手动启动一个自己写的服务呢?看了些代码都是用广播监听来开机启动的,我如何手动启动一个服务,难道要在activity里写一个intent?



广播监听事件是服务启动后才能监听的,前提是服务已经启动了.....如果是框架内的话,在systemserver中加载就可以了
  
Slog.i(TAG, "Input Method Service");     
imm = new InputMethodManagerService(context, statusBar);     
ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);   

   Slog.i(TAG, "Input Method Service");  
    imm = new InputMethodManagerService(context, statusBar);  
    ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);  


在activity中使用intent广播事件,是为了激活后台服务。不是很明白你所说的手动启动时啥意思?

钰云 发表于 2011-7-28 10:05 | 显示全部楼层
[quote="ishelf广播监听事件是服务启动后才能监听的,前提是服务已经启动了.....如果是框架内的话,在systemserver中加载就可以了
  
Slog.i(TAG, "Input Method Service");     
imm = new InputMethodManagerService(context, statusBar);     
ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);   

   Slog.i(TAG, "Input Method Service");  
    imm = new InputMethodManagerService(context, statusBar);  
    ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);  


那下面这种xml配置的方式是不是也可以开机自动启动服务呢?
  
<receiver android:name=".MyBootReceiver">     
            <intent-filter>     
                <action android:name="android.intent.action.BOOT_COMPLETED" />     
            </intent-filter>     
        </receiver>  

<receiver android:name=".MyBootReceiver">  
            <intent-filter>  
                <action android:name="android.intent.action.BOOT_COMPLETED" />  
            </intent-filter>  
        </receiver>

  
public void onReceive(Context arg0, Intent arg1) {      
   // 启动服务      
    Intent service = new Intent(arg0, MyService.class);      
   arg0.startService(service);      
}   

    public void onReceive(Context arg0, Intent arg1) {   
       // 启动服务   
        Intent service = new Intent(arg0, MyService.class);   
       arg0.startService(service);   
    }
如果说广播监听是广播这个类被实例后才能监听的,那怎么监听系统开机的广播呢?开机前不可能实例好广播的这个类的吧

broken 发表于 2011-7-28 10:05 | 显示全部楼层
busiying119
[quote="ishelf广播监听事件是服务启动后才能监听的,前提是服务已经启动了.....如果是框架内的话,在systemserver中加载就可以了
  
Slog.i(TAG, "Input Method Service");     
imm = new InputMethodManagerService(context, statusBar);     
ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);   

   Slog.i(TAG, "Input Method Service");  
    imm = new InputMethodManagerService(context, statusBar);  
    ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);  


那下面这种xml配置的方式是不是也可以开机自动启动服务呢?
  
<receiver android:name=".MyBootReceiver">     
            <intent-filter>     
                <action android:name="android.intent.action.BOOT_COMPLETED" />     
            </intent-filter>     
        </receiver>  

<receiver android:name=".MyBootReceiver">  
            <intent-filter>  
                <action android:name="android.intent.action.BOOT_COMPLETED" />  
            </intent-filter>  
        </receiver>

  
public void onReceive(Context arg0, Intent arg1) {      
   // 启动服务      
    Intent service = new Intent(arg0, MyService.class);      
   arg0.startService(service);      
}   

    public void onReceive(Context arg0, Intent arg1) {   
       // 启动服务   
        Intent service = new Intent(arg0, MyService.class);   
       arg0.startService(service);   
    }
如果说广播监听是广播这个类被实例后才能监听的,那怎么监听系统开机的广播呢?开机前不可能实例好广播的这个类的吧




1.监听特定事件需要相关的服务广播该事件,也就是说相关服务要启动(你的.MybootReceiver肯定是在ActivityManagerService之后启动的)。如果是activity的话,也可以广播事件,不过生命周期有限,不能一直跑在后台,可能我在解释的时候没有提及activity所以导致误解。
2.你的Receiver只能说明你可以监听到boot完成的事件,怎么可以自启动呢。
3.你的监听事件是为了启动一个新的服务,而不是为了监听某一个服务所发出的事件。


====该没什么问题了吧。我两说的不是一回事了,呵呵

gz-vps 发表于 2011-7-28 10:05 | 显示全部楼层
ishelf

1.监听特定事件需要相关的服务广播该事件,也就是说相关服务要启动(你的.MybootReceiver肯定是在ActivityManagerService之后启动的)。如果是activity的话,也可以广播事件,不过生命周期有限,不能一直跑在后台,可能我在解释的时候没有提及activity所以导致误解。
2.你的Receiver只能说明你可以监听到boot完成的事件,怎么可以自启动呢。
3.你的监听事件是为了启动一个新的服务,而不是为了监听某一个服务所发出的事件。


====该没什么问题了吧。我两说的不是一回事了,呵呵

谢~谢~楼~主啊~你的帖子促使我已经搞明白广播、启动服务、自定义广播,自动启动服务这些相关知识,不过我在真机上测试,xml配置的receiver是可以监听到boot完成的广播,然后启动我的服务的,从而达到开机自动启动服务的目的


RainyAlley 发表于 2012-8-9 15:16 | 显示全部楼层
问一下楼主:如何在后台启动服务?

我想做一个电话的拦截程序,如何让拦截的代码在后台运行。如果放在某个activity中的话,必须打开这个activity才能触发。
我现在需要能够这样:用开关控制是否拦截,而不局限于activity是否打开,或者我的这个应用是否运行 ?

我现在放在了activity中,必须打开这个activity才会拦截:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.patternset);
myPhoneStateListener = new MyPhoneStateListener();
phoner();
manager.listen(myPhoneStateListener,
PhoneStateListener.LISTEN_CALL_STATE);
}
您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-4-20 15:58 , Processed in 0.174846 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表