Search This Blog

18 February 2012

AIDL Step 6: Creating an updated client

Create our new module:

malachi@onyx:~/work/apkextensions$ mvn archetype:generate -DarchetypeCatalog=http://repository-malachid.forge.cloudbees.com/public-snapshot/archetype-catalog.xml
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building extension test 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] >>> maven-archetype-plugin:2.2:generate (default-cli) @ pom >>>
[INFO]
[INFO] <<< maven-archetype-plugin:2.2:generate (default-cli) @ pom <<<
[INFO]
[INFO] --- maven-archetype-plugin:2.2:generate (default-cli) @ pom ---
[INFO] Generating project in Interactive mode
[INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
Choose archetype:
1: http://repository-malachid.forge.cloudbees.com/public-snapshot/archetype-catalog.xml -> org.eoti.kryten:kryten-archetype (kryten-archetype)
2: http://repository-malachid.forge.cloudbees.com/public-snapshot/archetype-catalog.xml -> org.eoti.galatea:galatea-archetype (galatea-archetype)
3: http://repository-malachid.forge.cloudbees.com/public-snapshot/archetype-catalog.xml -> org.eoti.archtest:archtest-archetype (archtest-archetype)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 2
Define value for property 'groupId': : org.eoti.android.test.apkextensions.client2
Define value for property 'artifactId': : Client2
Define value for property 'version':  1.0-SNAPSHOT: :
Define value for property 'package':  org.eoti.android.test.apkextensions.client2: :
Confirm properties configuration:
groupId: org.eoti.android.test.apkextensions.client2
artifactId: Client2
version: 1.0-SNAPSHOT
package: org.eoti.android.test.apkextensions.client2
 Y: :
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: galatea-archetype:1.1-SNAPSHOT
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: org.eoti.android.test.apkextensions.client2
[INFO] Parameter: artifactId, Value: Client2
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: org.eoti.android.test.apkextensions.client2
[INFO] Parameter: packageInPathFormat, Value: org/eoti/android/test/apkextensions/client2
[INFO] Parameter: package, Value: org.eoti.android.test.apkextensions.client2
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: groupId, Value: org.eoti.android.test.apkextensions.client2
[INFO] Parameter: artifactId, Value: Client2
[WARNING] Don't override file /home/malachi/work/apkextensions/Client2/src/main/android/res/values/strings.xml
[WARNING] Don't override file /home/malachi/work/apkextensions/Client2/src/main/android/res/layout/main.xml
[INFO] project created from Archetype in dir: /home/malachi/work/apkextensions/Client2
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 19.317s
[INFO] Finished at: Sat Feb 18 08:09:07 PST 2012
[INFO] Final Memory: 11M/245M
[INFO] ------------------------------------------------------------------------


Take care of the keystore and dependency...

And replace our Client2Activity:
package org.eoti.android.test.apkextensions.client2;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import org.eoti.android.test.apkextensions.api.v2.IServer;
import org.eoti.android.test.apkextensions.api.v2.Registration;

public class Client2Activity extends Activity {
    private static String TAG = "Client2";

    private static final String REG_NAME = Client2Activity.class.getName();
    private static final String REG_VERSION = "1.0alpha";
    private enum State{Unbound,Bound,Connected,Disconnected}
    private State state = State.Unbound;
    private IServer server;

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            server = IServer.Stub.asInterface(iBinder);
            state = State.Connected;
            try {
                Log.d(TAG, "Server connected: " + server.getServerIdentifier());
                Registration registration = new Registration();
                registration.setName(REG_NAME);
                registration.setVersion(REG_VERSION);
                server.register(registration);
                Log.d(TAG, "Registered " + registration.getName());
            } catch (RemoteException e) {
                Log.e(TAG, "Unable to register", e);
            }

            doTest();
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            state = State.Disconnected;
            server = null;
            Log.d(TAG, "Server disconnected");
        }
    };

    private void bindServer()
    {
        switch(state)
        {
            case Bound:
            case Connected:
            case Disconnected:
                return;
            default:
                bindService(new Intent(IServer.class.getName()), connection, Context.BIND_AUTO_CREATE);
                state = State.Bound;
                Log.e(TAG, "Server bound");
                break;
        }
    }

    private void unbindServer()
    {
        switch(state)
        {
            case Unbound:
                return;
            case Connected:
                try{
                    server.unregister(REG_NAME);
                }catch(RemoteException e){
                    Log.e(TAG, "Unable to unregister", e);
                }
                server = null;
                // fall through
            default:
                unbindService(connection);
                state = State.Unbound;
                Log.e(TAG, "Server unbound");
                break;
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        bindServer();
    }

    @Override
    protected void onDestroy() {
        unbindServer();
        super.onDestroy();
    }

    protected void doTest()
    {
        Log.d(TAG, "Running tests...");
        // @TODO add tests here
        Log.d(TAG, "Tests done...");
        unbindServer();
    }
}

Build it... run it...
malachi@onyx:~/work/apkextensions$ cd Client2
malachi@onyx:~/work/apkextensions/Client2$ mvn clean install

I/ActivityManager(   61): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=org.eoti.android.test.apkextensions.client2/.Client2Activity } from pid 127
I/ActivityManager(   61): Start proc org.eoti.android.test.apkextensions.client2 for activity org.eoti.android.test.apkextensions.client2/.Client2Activity: pid=697 uid=10047 gids={1015}
I/ActivityManager(   61): Start proc org.eoti.android.test.apkextensions.server for service org.eoti.android.test.apkextensions.server/.TheServer: pid=705 uid=10045 gids={1015}
E/Client2 (  697): Server bound
I/ActivityManager(   61): Displayed org.eoti.android.test.apkextensions.client2/.Client2Activity: +1s67ms
D/Client2 (  697): Server connected: org.eoti.android.test.apkextensions.server.TheServer#1079078320
D/TheServer(  705): Registration received:  org.eoti.android.test.apkextensions.client2.Client2Activity v1.0alpha
D/Client2 (  697): Registered org.eoti.android.test.apkextensions.client2.Client2Activity
D/Client2 (  697): Running tests...
D/Client2 (  697): Tests done...
D/TheServer(  705): Registration removed: org.eoti.android.test.apkextensions.client2.Client2Activity
E/Client2 (  697): Server unbound
I/ActivityManager(   61): No longer want com.android.settings (pid 155): hidden #16


So we get deprecated messages when Client1 connects and the additional functionality when Client2 connects.
Client2 also has access to functionality that Client1 is unaware of.

Next up, AIDL Step 7: Using Callbacks

No comments:

Post a Comment