如何getSystemService()的工作是什么呢? [英] How does getSystemService() work exactly?

查看:182
本文介绍了如何getSystemService()的工作是什么呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前在 mLocationManager 的对象应该走出去的范围低于code第一眼后的onCreate(...)结束,且预期的行为是 onLocationChanged 没有被调用或者叫了几声,直到对象进行垃圾回收。但是,通过返回的对象的 getSystemService 似乎这住 MainActivity 的范围是单身(适当所以既然是系统服务:))

At first glance in the code below the mLocationManager object should go out of scope after onCreate(...) is finished, and the expected behaviour is that onLocationChanged is never called or called a few times until the object is garbage collected. However the object returned by the getSystemService seems to be singleton which lives outside the scope of MainActivity (appropriately so since it is a system service :) )

在采取堆转储,并通过它与Eclipse的内存分析器似乎ContextImpl有一个参考,一个LocationManager实例。在存储器转储有两个引用一个LocationManager对象而在code有清楚只有一个,这意味着另一参考创建别处。

After taking a heap dump and going through it with the Eclipse Memory Analyzer it seems that ContextImpl keeps a reference to a LocationManager instance. In the memory dump there were two references to a LocationManager object while in the code there is clearly only one, which means that another reference is created somewhere else.

我的问题是:

是否有人有要求的执行情况时,究竟是什么发生了一个完整的说明:

Does someone have a complete description of what is exactly happening when calling the implementation of:

public abstract Object getSystemService(String name);

是返回的对象延后创建一个独立的,并在那里恰恰是参照创建/保存?

is the object returned a singleton lazily created and where exactly is the reference created/kept ?

package com.neusoft.bump.client.storage;

import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.Menu;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.v("TAG", "STARTED");
        LocationManager mLocationManager = (LocationManager) this
                .getSystemService(Context.LOCATION_SERVICE);

        LocationListener locationListener = new LocationListener() {

            public void onLocationChanged(Location location) {
                Log.v("TAG", "onLocationChanged");
                Log.v("TAG", "Latitude: " + location.getLatitude()
                        + "Longitude: " + location.getLongitude());
            }

            public void onStatusChanged(String provider, int status,
                    Bundle extras) {}

            public void onProviderEnabled(String provider) {}

            public void onProviderDisabled(String provider) {}

        };

        // Register the listener with the Location Manager to receive location
        // updates
        mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                600, 0, locationListener);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

UPDATE1

LocationManager 为单创建

private LocationManager getLocationManager() {
    synchronized (sSync) {
        if (sLocationManager == null) {
            IBinder b = ServiceManager.getService(LOCATION_SERVICE);
            ILocationManager service = ILocationManager.Stub.asInterface(b);
            sLocationManager = new LocationManager(service);
        }
    }
    return sLocationManager;
}

但我听不太懂叫 ServiceManager.getService(LOCATION_SERVICE)时会发生什么; 读完本的ServiceManager code。

but I have trouble understanding what happens when calling ServiceManager.getService(LOCATION_SERVICE); even after reading the ServiceManager code.

推荐答案

看看我的讨论才有意义......

See if my discussion makes sense...

<一个href="https://docs.google.com/document/d/10EYlyuxDw1KPy7LJlGtgMz69gwMO-pjDHS2GRtppvZg/edit?usp=sharing">dissection Android的服务内部的

所建议的读者,我试图复制的写在这里的一些部分之一。

As suggested by one of the readers I am trying to copy some portion of the write-up here.

你有没有想过怎样的应用程序得到一个句柄系统服务,如电源管理器或活动管理器或位置管理器和其他几个人喜欢这些。要知道,我挖到了Android的源$ C ​​$ C,发现了这是如何在内部完成。 因此,让我从应用程序端的Java code开始。

Have you ever wondered how an app gets an handle to the system services like POWER MANAGER or ACTIVITY MANAGER or LOCATION MANAGER and several others like these. To know that I dug into the source code of Android and found out how this is done internally. So let me start from the application side’s java code.

在应用方面,我们必须调用函数的getService 并通过系统服务的ID(说POWER_SERVICE)获得一个句柄的服务。

At the application side we have to call the function getService and pass the ID of the system service (say POWER_SERVICE) to get an handle to the service.

下面是$ C $下的getService 在/frameworks/base/core/java/android/os/ServiceManager.java定义

Here is the code for getService defined in /frameworks/base/core/java/android/os/ServiceManager.java

    /**
44     * Returns a reference to a service with the given name.
45     *
46     * @param name the name of the service to get
47     * @return a reference to the service, or <code>null</code> if the service doesn't exist
48     */
49    public static IBinder getService(String name) {
50        try {
51            IBinder service = sCache.get(name);
52            if (service != null) {
53                return service;
54            } else {
55                return getIServiceManager().getService(name);
56            }
57        } catch (RemoteException e) {
58            Log.e(TAG, "error in getService", e);
59        }
60        return null;
61    }

假设我们没有在高速缓存的服务。因此,我们需要集中在线55上 返回getIServiceManager()的getService(名);

Suppose we don’t have the service in the cache. Hence we need to concentrate on line 55 return getIServiceManager().getService(name);

此调用实际上得到一个句柄到服务管理,并要求其返回的名字,我们作为一个参数传递,服务的参考

This call actually gets a handle to the service manager and asks it to return a reference of the service whose name we have passed as a parameter.

现在让我们来看看如何使用 getIServiceManager()函数返回一个句柄的ServiceManager。

Now let us see how the getIServiceManager() function returns a handle to the ServiceManager.

下面是getIserviceManager()从/frameworks/base/core/java/android/os/ServiceManager.java的code

Here is the code of getIserviceManager() from /frameworks/base/core/java/android/os/ServiceManager.java

private static IServiceManager getIServiceManager() {
34        if (sServiceManager != null) {
35            return sServiceManager;
36        }
37
38        // Find the service manager
39        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
40        return sServiceManager;
41    }

在ServicemanagerNative.asInterface()如下所示:

The ServicemanagerNative.asInterface() looks like the following:

/**
28     * Cast a Binder object into a service manager interface, generating
29     * a proxy if needed.
30     */
31    static public IServiceManager asInterface(IBinder obj)
32    {
33        if (obj == null) {
34            return null;
35        }
36        IServiceManager in =
37            (IServiceManager)obj.queryLocalInterface(descriptor);
38        if (in != null) {
39            return in;
40        }
41
42        return new ServiceManagerProxy(obj);
43    }

所以基本上我们得到的句柄,本地的ServiceManager。

So basically we are getting a handle to the native servicemanager.

这asInterface功能实际上是埋在两个宏 DECLARE_META_INTERFACE(的ServiceManager)在 IMPLEMENT_META_INTERFACE(的ServiceManager,android.os.IServiceManager); 分别IserviceManager.h和IServiceManager.cpp定义。

This asInterface function is actually buried inside the two macros DECLARE_META_INTERFACE(ServiceManager) and IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager"); defined in IserviceManager.h and IServiceManager.cpp respectively.

让我们深入到在/frameworks/base/include/binder/IInterface.h定义的两个宏

Lets delve into the two macros defined in /frameworks/base/include/binder/IInterface.h

DECLARE_META_INTERFACE(的ServiceManager)宏定义为

// ----------------------------------------------------------------------
73
74#define DECLARE_META_INTERFACE(INTERFACE)                               \
75    static const android::String16 descriptor;                          \
76    static android::sp<I##INTERFACE> asInterface(                       \
77            const android::sp<android::IBinder>& obj);                  \
78    virtual const android::String16& getInterfaceDescriptor() const;    \
79    I##INTERFACE();                                                     \
80    virtual ~I##INTERFACE();                                            \

IMPLEMENT_META_INTERFACE(的ServiceManager,android.os.IServiceManager); 已被定义如下:

#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
84    const android::String16 I##INTERFACE::descriptor(NAME);             \
85    const android::String16&                                            \
86            I##INTERFACE::getInterfaceDescriptor() const {              \
87        return I##INTERFACE::descriptor;                                \
88    }                                                                   \
89    android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \
90            const android::sp<android::IBinder>& obj)                   \
91    {                                                                   \
92        android::sp<I##INTERFACE> intr;                                 \
93        if (obj != NULL) {                                              \
94            intr = static_cast<I##INTERFACE*>(                          \
95                obj->queryLocalInterface(                               \
96                        I##INTERFACE::descriptor).get());               \
97            if (intr == NULL) {                                         \
98                intr = new Bp##INTERFACE(obj);                          \
99            }                                                           \
100        }                                                               \
101        return intr;                                                    \
102    }                                                                   \
103    I##INTERFACE::I##INTERFACE() { }                                    \
104    I##INTERFACE::~I##INTERFACE() { }

所以,如果我们将扩大在IServiceManager.h和放这两个宏; IServiceManager.cpp文件,它们看起来像下面相应的替代参数:

So if we replace expand these two macros in IServiceManager.h & IServiceManager.cpp file with the appropriate replacement parameters they look like the following:

class IServiceManager : public IInterface
{
public:
   static const android::String16 descriptor;  
    static android::sp<IServiceManager> asInterface( const android::sp<android::IBinder>& obj);  
    virtual const android::String16& getInterfaceDescriptor() const; 
    IServicemanager();  
    virtual ~IServiceManager();  
…......
….....
…...
…..

和中 IServiceManager.cpp

And in IServiceManager.cpp

const android::String16 IServiceManager::descriptor("android.os.IServiceManager");             
const android::String16&  
       IServiceManager::getInterfaceDescriptor() const {  
    return  IServiceManager::descriptor;
}    
android::sp<IServiceManager> IServiceManager::asInterface(   
        const android::sp<android::IBinder>& obj)  
{   
    android::sp< IServiceManager> intr;    
    if (obj != NULL) {     
        intr = static_cast<IServiceManager*>(   
            obj->queryLocalInterface(  
                    IServiceManager::descriptor).get());    
        if (intr == NULL) {   
            intr = new BpServiceManager(obj);  
        }  
    }     
    return intr;    
}     
IServiceManager::IServiceManager() { }    
IServiceManager::~IIServiceManager { } 

所以,如果你看行12,显示如果服务管理器启动并运行(它应该是因为服务管理器中的Andr​​oid启动了init进程启动)它通过queryLocalinterface函数返回引用它,它上升一路的Java接口。

So if you see the line 12 which shows if the Service Manager is up and running (and it should because the service manager starts in the init process during Android boot up) it returns the reference to it through the queryLocalinterface function and it goes up all the way to the java interface.

public IBinder getService(String name) throws RemoteException {
116        Parcel data = Parcel.obtain();
117        Parcel reply = Parcel.obtain();
118        data.writeInterfaceToken(IServiceManager.descriptor);
119        data.writeString(name);
120        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
121        IBinder binder = reply.readStrongBinder();
122        reply.recycle();
123        data.recycle();
124        return binder;
125    }

从ServiceManagerNative.java。在这个函数中,我们通过我们所需要的服务。

from ServiceManagerNative.java. In this function we pass the service that we are looking for.

而onTransact功能GET_SERVICE_TRANSACTION远程存根看起来如下:

And the onTransact function for GET_SERVICE_TRANSACTION on the remote stub looks like the following:

public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
51    {
52        try {
53            switch (code) {
54            case IServiceManager.GET_SERVICE_TRANSACTION: {
55                data.enforceInterface(IServiceManager.descriptor);
56                String name = data.readString();
57                IBinder service = getService(name);
58                reply.writeStrongBinder(service);
59                return true;
60            }
61
62            case IServiceManager.CHECK_SERVICE_TRANSACTION: {
63                data.enforceInterface(IServiceManager.descriptor);
64                String name = data.readString();
65                IBinder service = checkService(name);
66                reply.writeStrongBinder(service);
67                return true;
68            }
69
//Rest has been discarded for brevity…………………..

………………….
………………….
…………………

它返回通过函数的getService引用到所需的服务。 从/frameworks/base/libs/binder/IServiceManager.cpp的的getService功能 如下所示:

It returns the reference to the needed service through the function getService. The getService function from /frameworks/base/libs/binder/IServiceManager.cpp looks like the following:

  virtual sp<IBinder> getService(const String16& name) const
134    {
135        unsigned n;
136        for (n = 0; n < 5; n++){
137            sp<IBinder> svc = checkService(name);
138            if (svc != NULL) return svc;
139            LOGI("Waiting for service %s...\n", String8(name).string());
140            sleep(1);
141        }
142        return NULL;
143    }

因此​​,它实际上是检查是否服务可用,然后返回一个参考吧。在这里我想补充一点,当我们返回一个引用一个IBinder对象,不像其他的数据类型它不会在客户端的地址空间中复制,但它实际上是的IBinder对象是通过共享到客户端相同的参考特殊的技术,称为对象映射在活页夹中的驱动程序。

So it actually checks if the Service is available and then returns a reference to it. Here I would like to add that when we return a reference to an IBinder object, unlike other data types it does not get copied in the client’s address space, but it's actually the same reference of the IBinder object which is shared to the client through a special technique called object mapping in the Binder driver.

要添加更多细节的讨论,让我去一点点深入了。

To add more details to the discussion, let me go a little deeper into it.

在checkService功能如下所示:

The checkService function looks like the following:

virtual sp<IBinder> checkService( const String16& name) const

    {
        Parcel data, reply;

        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());

        data.writeString16(name);

        remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);

        return reply.readStrongBinder();

    }

所以它实际上调用远程服务,并通过CHECK_SERVICE_TRANSACTION code(2它的一个枚举值)吧。

So it actually calls a remote service and pass CHECK_SERVICE_TRANSACTION code (its an enum value of 2) to it.

这个远程服务实际上是在框架/基/命令/的ServiceManager / service_manager.c实施 其onTransact看起来像下面这样。

This remote service is actually implemented in frameworks/base/cmds/servicemanager/service_manager.c and its onTransact looks like the following.

switch(txn->code) {
   case SVC_MGR_GET_SERVICE:
           case SVC_MGR_CHECK_SERVICE:
        s = bio_get_string16(msg, &len);
        ptr = do_find_service(bs, s, len);
        if (!ptr)
            break;
        bio_put_ref(reply, ptr);
        return 0;

因此​​,我们最终会调用该函数命名do_find_service它得到一个参考服务,并返回了回去。

Hence we end up calling the function named do_find_service which gets a reference to the service and returns it back.

从同一个文件中的do_find_service如下所示:

The do_find_service from the same file looks as follows:

void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len)

{

    struct svcinfo *si;

    si = find_svc(s, len);



//    ALOGI("check_service('%s') ptr = %p\n", str8(s), si ? si->ptr : 0);

    if (si && si->ptr) {

        return si->ptr;

    } else {

        return 0;

    }

find_svc如下所示:

find_svc looks as follows:

struct svcinfo *find_svc(uint16_t *s16, unsigned len)

{

    struct svcinfo *si;



    for (si = svclist; si; si = si->next) {

        if ((len == si->len) &&

            !memcmp(s16, si->name, len * sizeof(uint16_t))) {

            return si;

        }

    }

    return 0;

}

由于它变得清晰,它遍历svclist并返回,我们正在寻找的服务。

As it becomes clear that it traverses through the svclist and returns the the service we are looking for.

这篇关于如何getSystemService()的工作是什么呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆