Using xml Syntax Highlighting
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.service"
- android:versionCode="1"
- android:versionName="1.0">
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <!-- Service -->
- <service android:name=".service.Service"
- android:enabled="true"
- android:exported="true"
- android:process=":remote">
- <intent-filter>
- <action android:name="com.example.service.IService" />
- </intent-filter>
- </service>
- <!-- Activity -->
- <activity android:name=".app.Activity" android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
- <uses-sdk android:minSdkVersion="3" />
- </manifest>
Parsed in 0.004 seconds, using GeSHi 1.0.8.4
And your service supports this interface:
Using java Syntax Highlighting
- package com.example.service;
- interface IService {
- int getPid();
- }
Parsed in 0.030 seconds, using GeSHi 1.0.8.4
Suppose we have an Activity with three buttons to bind/unbind/check the service. This is how you would use my connection proxy to interact with the service from the activity:
Using java Syntax Highlighting
- package com.example.service.app;
- import android.content.*;
- import android.os.*;
- import android.util.*;
- import android.view.*;
- import android.widget.*;
- import com.example.service.*;
- public class Activity extends android.app.Activity {
- public static final String TAG = Activity.class.getSimpleName();
- private IService service = Connection.create(IService.class);
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- final IConnection connection = (IConnection)service;
- final Button bindServiceButton = (Button) findViewById(R.id.bindservice);
- bindServiceButton.setOnClickListener(new View.OnClickListener() {
- public void onClick(View view) {
- connection.bind(Activity.this, Context.BIND_AUTO_CREATE);
- }
- });
- final Button unbindServiceButton = (Button) findViewById(R.id.unbindservice);
- unbindServiceButton.setOnClickListener(new View.OnClickListener() {
- public void onClick(View view) {
- connection.unbind(Activity.this);
- }
- });
- final Button checkServiceButton = (Button) findViewById(R.id.checkservice);
- unbindServiceButton.setOnClickListener(new View.OnClickListener() {
- public void onClick(View view) {
- Toast.makeText(Activity.this, "The service is" + (connection.isConnected()?"":" not") + " connected.", Toast.LENGTH_SHORT).show();
- }
- });
- connection.addOnConnected(new Runnable() {
- @Override
- public void run() {
- try {
- Log.w(TAG, "Connected. (Pid: " + service.getPid() + ")");
- bindServiceButton.setEnabled(false);
- unbindServiceButton.setEnabled(true);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
- });
- connection.addOnDisconnected(new Runnable() {
- @Override
- public void run() {
- Log.w(TAG, "Disconnected.");
- bindServiceButton.setEnabled(true);
- unbindServiceButton.setEnabled(false);
- }
- });
- connection.bind(this, Context.BIND_AUTO_CREATE);
- }
- @Override
- public void onDestroy() {
- final IConnection connection = (IConnection)service;
- connection.unbind(this);
- super.onDestroy();
- }
- }
Parsed in 0.040 seconds, using GeSHi 1.0.8.4
Now, at first this may seem similar to the way it is done in the standard android API. However, there are several simplifications. The ServiceConnection is managed by the proxy. The user can use IConnection::isConnected() to query whether the service is bound. It is very easy for the user to invoke the methods of the IService interface. If the user invokes a method from the IService interface while the service is not bound, an exception will be raised (I'm not sure yet if it's a good idea to use RemoteException for this). The user can also run code when a binding is created or destroyed (addOnConnected/addOnDisconnected). OnDisconnected also fires on IConnection::unbind() so the state transitions are always:
[align=center][Unbound]---onConnected-->[Bound] and [Bound]---onDiconnected-->[Unbound][/align]
(Unlike the asymetrical ServiceConnection::onServiceConnected/ServiceConnection::onServiceDisconnected, where onServiceDisconnected is only called if the service is stopped/killed.)
Any comments or suggestions so far?


