Search This Blog

18 February 2012

AIDL Step 3: Creating the Client

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.client1
Define value for property 'artifactId': : Client1
Define value for property 'version':  1.0-SNAPSHOT: :
Define value for property 'package':  org.eoti.android.test.apkextensions.client1: :
Confirm properties configuration:
groupId: org.eoti.android.test.apkextensions.client1
artifactId: Client1
version: 1.0-SNAPSHOT
package: org.eoti.android.test.apkextensions.client1
 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.client1
[INFO] Parameter: artifactId, Value: Client1
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: org.eoti.android.test.apkextensions.client1
[INFO] Parameter: packageInPathFormat, Value: org/eoti/android/test/apkextensions/client1
[INFO] Parameter: package, Value: org.eoti.android.test.apkextensions.client1
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: groupId, Value: org.eoti.android.test.apkextensions.client1
[INFO] Parameter: artifactId, Value: Client1
[WARNING] Don't override file /home/malachi/work/apkextensions/Client1/src/main/android/res/values/strings.xml
[WARNING] Don't override file /home/malachi/work/apkextensions/Client1/src/main/android/res/layout/main.xml
[INFO] project created from Archetype in dir: /home/malachi/work/apkextensions/Client1
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 25.201s
[INFO] Finished at: Sat Feb 18 07:32:17 PST 2012
[INFO] Final Memory: 13M/309M
[INFO] ------------------------------------------------------------------------


Take care of the keystore stuff in the pom...
and add the dependency:
        <dependency>
            <groupId>org.eoti.android.test.apkextensions.api</groupId>
            <artifactId>API</artifactId>
            <version>1.0-SNAPSHOT</version>
            <type>apklib</type>
        </dependency>
       
edit your Client1/src/main/java/org/eoti/android/test/apkextensions/client1/Client1Activity.java
package org.eoti.android.test.apkextensions.client1;

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.v1.IServer;
import org.eoti.android.test.apkextensions.api.v1.Registration;

public class Client1Activity extends Activity {
    private static String TAG = "Client1";

    private static final String REG_NAME = Client1Activity.class.getName();
    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;
            Log.d(TAG, "Server connected");
            try {
                Registration registration = new Registration();
                registration.setName(REG_NAME);
                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();
    }
}


Let's compile it
malachi@onyx:~/work/apkextensions$ cd Client1
malachi@onyx:~/work/apkextensions/Client1$ mvn clean install

To verify it is working, watch logcat as you launch Client1
I/ActivityManager(   61): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=org.eoti.android.test.apkextensions.client1/.Client1Activity } from pid 127
I/ActivityManager(   61): Start proc org.eoti.android.test.apkextensions.client1 for activity org.eoti.android.test.apkextensions.client1/.Client1Activity: pid=546 uid=10046 gids={1015}
I/ARMAssembler(   61): generated scanline__00000177:03515104_00001002_00000000 [ 87 ipp] (110 ins) at [0x445306f0:0x445308a8] in 538806 ns
I/ActivityManager(   61): Start proc org.eoti.android.test.apkextensions.server for service org.eoti.android.test.apkextensions.server/.TheServer: pid=554 uid=10045 gids={1015}
E/Client1 (  546): Server bound
I/ActivityManager(   61): Displayed org.eoti.android.test.apkextensions.client1/.Client1Activity: +1s140ms (total +10h57m29s956ms)
D/Client1 (  546): Server connected
D/TheServer(  554): Registration received:  org.eoti.android.test.apkextensions.client1.Client1Activity
D/Client1 (  546): Registered org.eoti.android.test.apkextensions.client1.Client1Activity
D/Client1 (  546): Running tests...
D/Client1 (  546): Tests done...
D/TheServer(  554): Registration removed: org.eoti.android.test.apkextensions.client1.Client1Activity
E/Client1 (  546): Server unbound


If you'd like to recompile everything at once, you can also use a top-level POM:


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.eoti.android.test.apkextensions</groupId>
    <artifactId>pom</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>extension test</name>

    <modules>
        <module>API</module>
        <module>TheServer</module>
        <module>Client1</module>
  </modules>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <phase>package</phase>
                        <configuration>
                            <includeScope>runtime</includeScope>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
   

Just make sure that if you do, you update it whenever adding new modules.  IntelliJ will generally do that for you. Not sure about Eclipse.


So far, so good.  Now, let's try upgrading to a new version :)

Next up, AIDL Step 4: Upgrading the API

No comments:

Post a Comment