Android 本地服务示例、bindservice() 和 ServiceConnection()

发布于 2024-11-16 06:12:20 字数 595 浏览 3 评论 0原文

我有一个与 @mnish 大约一年前提出的问题相关的问题。

请看看他的问题和代码。他实现了一个ServiceConnection()并将其传递给bindService()。这遵循顶部附近的 Service 文档中的本地服务示例。

我想实现本地服务示例,因此我尝试添加 @mnish 问题/答案中的一些详细信息。在 ServiceConnection() 中 @mnish 的这一行让我感到困惑:

mService = ILocService.Stub.asInterface(iservice);

我理解 @mnish 写了这段代码,但是有人知道 ILocService 是什么以及我如何创建自己的 ILocService 吗?这个构造记录在哪里?我需要它吗?另外IBinder iservice的价值从何而来?

I have a question which is related to this question that was asked by @mnish about a year ago.

Please have a look at his question and code. He implements a ServiceConnection() and passes it to bindService(). This follows the Local Service Sample in the Service documentation near the top.

I want to implement the Local Service Sample, so I am trying to add some details from @mnish question/answer. In ServiceConnection() @mnish has this line that confuses me:

mService = ILocService.Stub.asInterface(iservice);

I understand @mnish wrote this code, but does anybody have any idea what ILocService is and any idea how I might go about creating my own ILocService? Where is this construct documented and do I need it? Also where does the value for IBinder iservice come from?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我们只是彼此的过ke 2024-11-23 06:12:20

他可能正在使用 Android 接口定义语言 (AIDL)
http://developer.android.com/guide/components/aidl.html

因此,他必须使用服务器端实现的存根,如记录的那样:

 // This is called when the connection with the service has been
 // established, giving us the service object we can use to
 // interact with the service.  We are communicating with our
 // service through an IDL interface, so get a client-side
 // representation of that from the raw service object.
 mService = IRemoteService.Stub.asInterface(service);

iservice 引用来自 onServiceConnected 方法,该方法在将服务绑定到您的活动后调用。调用bindService 会传递实现onServiceConnected 方法的ServiceConnection。

当服务的实现是本地的时,您不需要“IRemoteService.Stub.asInterface(service)”,那么您可以将服务强制转换为本地服务。

本地服务示例在服务中执行此操作:

public class LocalService extends Service {
    private NotificationManager mNM;

    // Unique Identification Number for the Notification.
    // We use it on Notification start, and to cancel it.
    private int NOTIFICATION = R.string.local_service_started;

    /**
     * Class for clients to access.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with
     * IPC.
     */
    public class LocalBinder extends Binder {
        LocalService getService() {
        return LocalService.this;
        }
    }

    ...

}

在 ServiceConnection 类的 Activity 中执行此操作:

private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
        // This is called when the connection with the service has been
        // established, giving us the service object we can use to
        // interact with the service.  Because we have bound to a explicit
        // service that we know is running in our own process, we can
        // cast its IBinder to a concrete class and directly access it.
        mBoundService = ((LocalService.LocalBinder)service).getService();

        // Tell the user about this for our demo.
        Toast.makeText(Binding.this, R.string.local_service_connected,
                Toast.LENGTH_SHORT).show();
    }

    public void onServiceDisconnected(ComponentName className) {
        // This is called when the connection with the service has been
        // unexpectedly disconnected -- that is, its process crashed.
        // Because it is running in our same process, we should never
        // see this happen.
        mBoundService = null;
        Toast.makeText(Binding.this, R.string.local_service_disconnected,
            Toast.LENGTH_SHORT).show();
    }
};

He is probably using Android Interface Definition Language (AIDL)
http://developer.android.com/guide/components/aidl.html

Therefore he has to use a stub of the server side implementation like documented:

 // This is called when the connection with the service has been
 // established, giving us the service object we can use to
 // interact with the service.  We are communicating with our
 // service through an IDL interface, so get a client-side
 // representation of that from the raw service object.
 mService = IRemoteService.Stub.asInterface(service);

The iservice reference is coming from the onServiceConnected method which is called after binding the service to your activity. The call bindService gets passed the ServiceConnection which implements the onServiceConnected method.

You don't need the "IRemoteService.Stub.asInterface(service)" when your implementation of the service is local, then you can just cast the service to you local service.

The local service sample does this in the service:

public class LocalService extends Service {
    private NotificationManager mNM;

    // Unique Identification Number for the Notification.
    // We use it on Notification start, and to cancel it.
    private int NOTIFICATION = R.string.local_service_started;

    /**
     * Class for clients to access.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with
     * IPC.
     */
    public class LocalBinder extends Binder {
        LocalService getService() {
        return LocalService.this;
        }
    }

    ...

}

And this in the Activity in the ServiceConnection class:

private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
        // This is called when the connection with the service has been
        // established, giving us the service object we can use to
        // interact with the service.  Because we have bound to a explicit
        // service that we know is running in our own process, we can
        // cast its IBinder to a concrete class and directly access it.
        mBoundService = ((LocalService.LocalBinder)service).getService();

        // Tell the user about this for our demo.
        Toast.makeText(Binding.this, R.string.local_service_connected,
                Toast.LENGTH_SHORT).show();
    }

    public void onServiceDisconnected(ComponentName className) {
        // This is called when the connection with the service has been
        // unexpectedly disconnected -- that is, its process crashed.
        // Because it is running in our same process, we should never
        // see this happen.
        mBoundService = null;
        Toast.makeText(Binding.this, R.string.local_service_disconnected,
            Toast.LENGTH_SHORT).show();
    }
};
绾颜 2024-11-23 06:12:20

在这里,我的例子..会让你清楚,哈哈

// My MyServiceInterface.aidl
package com.mad.exam;

interface MyServiceInterface {
     int getNumber();
}

//MyService 
public class MyService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        Toast.makeText(this, "Service OnBind()", Toast.LENGTH_LONG).show();
        return mBinder;
    }

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        Toast.makeText(this, "Service Created", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        Toast.makeText(this, "Service Destroyed ", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onStart(Intent intent, int startId) {
        // TODO Auto-generated method stub
        super.onStart(intent, startId);
        Toast.makeText(this, "Service Started ", Toast.LENGTH_SHORT).show();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        // TODO Auto-generated method stub
        return super.onUnbind(intent);
    }

    private final MyServiceInterface.Stub mBinder = new MyServiceInterface.Stub() {
        public int getNumber() {
            return new Random().nextInt(100);
        }
    };
}

//My Activity 
public class ServiceDemo extends Activity implements OnClickListener {
    MyServiceInterface mService;
    ServiceConnection mConnection;
    Button retreive;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.service);
        retreive = (Button) findViewById(R.id.retreive);
        retreive.setOnClickListener(this);

        mConnection = new ServiceConnection() {

            public void onServiceDisconnected(ComponentName name) {
                // TODO Auto-generated method stub
            }

            public void onServiceConnected(ComponentName name, IBinder service) {
                // TODO Auto-generated method stub
                mService = MyServiceInterface.Stub.asInterface(service);

                try {
                    int i;
                    i = mService.getNumber();
                    Toast.makeText(ServiceDemo.this, "The service value is: " + String.valueOf(i), Toast.LENGTH_SHORT).show();
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
    }

    public void onClick(View v) {
        // TODO Auto-generated method stub
        Log.i("My Tag", "Clicked");
        Button btn = (Button) v;
        Intent callService = new Intent(this, MyService.class);
        bindService(callService, mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStart() {
        // TODO Auto-generated method stub
        super.onStart();
        Intent callService = new Intent(this, MyService.class);
        bindService(callService, mConnection, Context.BIND_AUTO_CREATE);
    }
}

Here you are, my example .. will make you clear about that LOL

// My MyServiceInterface.aidl
package com.mad.exam;

interface MyServiceInterface {
     int getNumber();
}

//MyService 
public class MyService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        Toast.makeText(this, "Service OnBind()", Toast.LENGTH_LONG).show();
        return mBinder;
    }

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        Toast.makeText(this, "Service Created", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        Toast.makeText(this, "Service Destroyed ", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onStart(Intent intent, int startId) {
        // TODO Auto-generated method stub
        super.onStart(intent, startId);
        Toast.makeText(this, "Service Started ", Toast.LENGTH_SHORT).show();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        // TODO Auto-generated method stub
        return super.onUnbind(intent);
    }

    private final MyServiceInterface.Stub mBinder = new MyServiceInterface.Stub() {
        public int getNumber() {
            return new Random().nextInt(100);
        }
    };
}

//My Activity 
public class ServiceDemo extends Activity implements OnClickListener {
    MyServiceInterface mService;
    ServiceConnection mConnection;
    Button retreive;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.service);
        retreive = (Button) findViewById(R.id.retreive);
        retreive.setOnClickListener(this);

        mConnection = new ServiceConnection() {

            public void onServiceDisconnected(ComponentName name) {
                // TODO Auto-generated method stub
            }

            public void onServiceConnected(ComponentName name, IBinder service) {
                // TODO Auto-generated method stub
                mService = MyServiceInterface.Stub.asInterface(service);

                try {
                    int i;
                    i = mService.getNumber();
                    Toast.makeText(ServiceDemo.this, "The service value is: " + String.valueOf(i), Toast.LENGTH_SHORT).show();
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
    }

    public void onClick(View v) {
        // TODO Auto-generated method stub
        Log.i("My Tag", "Clicked");
        Button btn = (Button) v;
        Intent callService = new Intent(this, MyService.class);
        bindService(callService, mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStart() {
        // TODO Auto-generated method stub
        super.onStart();
        Intent callService = new Intent(this, MyService.class);
        bindService(callService, mConnection, Context.BIND_AUTO_CREATE);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文