ラベル Java の投稿を表示しています。 すべての投稿を表示
ラベル Java の投稿を表示しています。 すべての投稿を表示

2013年2月28日木曜日

GoogleのBaaS「Cloud Endpoints」で簡単モバイルアプリ開発

Googleもモバイル向けのBaaSである「Cloud Endpoints」というものを出しました。これは、Google App Engine上で作ったサービスを簡単にAndroidやiOSなどのモバイルからREST APIとしてアクセスできるようにするためのものです。



もう少し言うと、App Engine上で、JavaやPythonを用いて作ったクラスとメソッドから、サーバサイドのRESTインターフェースとそのクライアントサイドのJavaScriptJava(Android用)Objective-C(iOS用)コードを生成してくれるものです。AndroidやiOS、もしくはWebアプリなどから簡単に生成したコードをコールすることで、App Engineのメソッドをシームレスにコールすることができます。

App Engineの開発でJavaを利用する場合に必要なものとしては、Google App Engine Java SDK 1.7.5以上と、Eclipseで開発するのであればGoogle Plugin for Eclipse(GPE)。
※ちなみにSDK1.7.5からはJava7も利用可能とのこと。


開発手順としては、

  1. App Engine上でバックエンドのサービス(メソッド)を実装。(もちろんApp Engineを使えば、認証、NoSQL、ストレージ、メールなどの多くの機能も利用可能。)
  2. 公開したいサービスのクラスに@Apiというアノテーションを付与し、メソッドに@ApiMethodというアノテーションを付与。
  3. そのアノテーションを付けたサービスから、endpoints.shユーティリティを使って、RESTインターフェースとJavaScript、Java、Objective-Cを生成。(GPEを使えば簡単に生成)
  4. その生成されたクライアントコードを使って、クライアントのアプリを実装。
  5. App Engineと同様のやり方でデプロイ。
これで、App Engine上にサービスを簡単にコールできるアプリが完成し、APIは「APIs Console」から参照できるようである。

JavaScriptも生成されることから、PhoneGapなどのWebKitベースのモバイルアプリからも利用できまるので、非常に便利ですね。

また、使った際には報告します!

2012年12月29日土曜日

Node.jsが面白い件⑨ ログ

Javaの場合にログと言えばlog4jが有名ですが、Node.jsで使えるlog4js-nodeが公開されています。ログローテーションやコンソールでのカラー表示などを提供し、簡単な操作でログの書き込みができます。プログラムを見て行きましょう。まずはインストール。

> npm install log4js

log4jsのexample.jsを少し変えたものが以下です。

var log4js = require('log4js');

// appenderによる出力指定。log4js.jsonファイルを読み込む。
log4js.configure('log4js.json', {});

// appenderのうち、file_logを指定。
var logger = log4js.getLogger('file_log');
logger.setLevel('TRACE');

logger.trace('これはトレース');
logger.debug('これはデバグ');
logger.info('これはインフォメーション');
logger.warn('これは警告');
logger.error('これはエラー');
logger.fatal('これは致命的エラー');

これを実行すると、以下の結果が表示されます。

[2012-12-28 23:31:15.100] [TRACE] file_log - これはトレース
[2012-12-28 23:31:15.107] [DEBUG] file_log - これはデバグ
[2012-12-28 23:31:15.108] [INFO] file_log - これはインフォメーション
[2012-12-28 23:31:15.108] [WARN] file_log - これは警告
[2012-12-28 23:31:15.108] [ERROR] file_log - これはエラー
[2012-12-28 23:31:15.108] [FATAL] file_log - これは致命的エラー

本当はカラー表示されるので、実際に出力してみてください。上記の例では、最初にlog4js.jsonという別ファイルを読み込んでいます。直接このファイルに書き込む事もできますが、例のように別ファイルで記述しているとデフォルトで60秒に1度更新チェックがかかり、更新されているとリロードしてくれるので便利です(更新チェックの間隔は変更できます)。以下が今回使ったlog4js.jsonの内容です。

{
  "appenders" : [
    { "type" : "console" },
    { "type" : "file", "filename" : "file_log.log", "category" : "file_log" },
    { "type" : "dateFile", "filename" : "date_log.log", "pattern" : "-yyyy-MM-dd-hh-mm", "category" : "date_log" }
  ]

例の7行目でfile_logを呼んでいますが、appendersで2つ目に設定しているfileログです。上に示した結果はコンソールの結果ですが、file_log.logにも同様の結果が追記されています。
また、file_logではなくdate_logを指定すると、date_log.logに結果が追記されます。file_logとdate_logの違いは、appenderのタイプの違いですが、date_logは指定したpatternに基づいてログローテーションを実施してくれます。例えば上記のパターンでは分単位でログローテーションを実施してくれます(新たな書き込みがあった時に分が進んでいると新しいログファイルに書き込みます)。
最後に、setLevel()で出力するログレベルを設定できるのでデバグ作業などに便利です。

他にもいくつかappendersが作成されていますが、Multiprocessは試してみても良いかもしれません。

2012年11月13日火曜日

MyBatis/iBATIS用のコードを自動生成する「MyBatis Generator」を使う

前回は、MyBatisの基本的な使い方を見てきました。今回はそこで手作業にて行ってきた各ファイルの自動生成ツール「MyBatis Generator」の使い方を説明していきたいと思っています。

MyBatis Generator Eclipse pluginのセットアップ
EclipseのメニューからHelp -> New Install Softwareを選択し、以下のURLを入力することでEclipse pluginがセットアップされます。
http://mybatis.googlecode.com/svn/sub-projects/generator/trunk/eclipse/UpdateSite/

インストールできましたら、メニューからFile -> New -> Other...を選択し、MyBatis Generator Configuration Fileを指定して、設定ファイル(デフォルトではgeneratorConfig.xml)を生成し、環境に合わせて編集します。このファイルは、Generateするための設定情報です。


  
    
    
    
    
    

各タグの説明ですが、javaModelGeneratorタグはエンティティクラスファイル、sqlMapGeneratorタグはXMLのMapperファイル、javaClientGeneratorタグはMapperクラスファイルの出力先を指定するためのタグです。tableタグで対象とするテーブル名を記述します。このtableNameにはワイルドカードも指定できるようです。ファイル編集後は、このgeneratorConfig.xmlを選択して、右クリックで「Generate MyBatis/iBATIS Artifacts」を選択しますと、エンティティクラスファイルとMapperファイル、Mapperクラス、Exampleクラスの4つのファイルが生成されます。(ちなみにMyBatis用だけでなく、2.2以上のiBATIS以上のファイルを生成できるようです。)

例えば、blogテーブルの場合は以下の4つのファイルが生成。
  • Blog.java :エンティティクラス。
  • BlogExample.java :Generator独自のクラスっぽい。SQL を呼び出す際、条件を指定するために利用するクラス。
  • BlogMapper.java :クエリを実行するための Java インターフェイス。
  • BlogMapper.xml :Mapper XML ファイルで、ほとんどの SQL はこのファイルに記述。
ちなみに、自動生成された JavaとXML ファイルのコメントには@mbggeneratedというアノテーションがあります。MyBatis Generatorが再度コードを生成するとき、このアノテーションが付加された要素だけを削除してから再度新しい要素を生成されます。そのため、このアノテーションがある場合は、手動で修正すると消えてしまいますのでご注意を。 話はそれましたが、続けますとBlogMapper.xmlを前回のように、mybatis-config.xmlのmapperタグに記述されていればデータベースアクセスできるようになります。例えば以下のようなコードでレコードを登録して、件数をカウントするということが簡単にできます。

BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = new Blog();
blog.setId(0);
blog.setContent("Test-Test");
mapper.insert(blog);
int count = mapper.countByExample(new BlogExample());
System.out.println(count);
session.close();

myBatis Generatorをカスタマイズ
このMyBatis GeneratorをPluginを作ることで、カスタマイズできます。具体的にはファイル名やクラス名を変えたり、インターフェースやスーパークラスを追加できたり、メソッド、コンストラクタなどを追加できたりと、結構いろいろ生成するファイルを変更することができます。
まずはここから"Mapping Generator"をダウンロードして、解凍します。そのmybatis-generator-core-x.x.x.jarファイル(私は1.3.2を利用)をEclipseにコピーして、ビルドパスを設定します。
次にorg.mybatis.generator.api.PluginAdapterを継承したクラスを作成します。このクラス内で生成するタイミングに合わせてオーバーライドするメソッドを選択肢、中身を実装します。(例えば、初期化時ならinitializedメソッドをオーバーライド。)以下の例では、エンティティクラスを生成する際に、エンティティクラスにコンストラクタを追加するというサンプルです。

package com.test.generator.plugins;

import java.util.List;

import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.TopLevelClass;

public class GenPlugin extends PluginAdapter {

 @Override
 public boolean validate(List arg) {
  return true;
 }

 @Override
 public void initialized(IntrospectedTable introspectedTable) {
  super.initialized(introspectedTable);
 }

 @Override
 public boolean modelBaseRecordClassGenerated(
   TopLevelClass topLevelClass,
   IntrospectedTable introspectedTable) {
  Method method = new Method();
  method.setVisibility(JavaVisibility.PUBLIC);
  method.setConstructor(true);
  method.setName(topLevelClass.getType().getShortName());
  method.addBodyLine("System.out.println(\"Called constructor\");");
  topLevelClass.addMethod(method);
  return super.modelBaseRecordClassGenerated(topLevelClass, introspectedTable);
 }
}

この作成したクラスをgeneratorConfig.xmlにcontextタグの中にpluginタグとして、追加します。

  
    
       .....
  

そうすると以下のコンストラクタがBlogクラスに追加されます。

public Blog() {
 System.out.println("Called constructor");
}

このプラグイン機能でいろいろと生成もいじれそうなので、開発の生産性向上に役立ちそうですね。

外部キーなどの対応
ここまで来たら、以下のように参照関係のあるテーブルの場合に自動生成してくれるかを試してみようと思います。

CREATE TABLE blog (
  id INT,
  content VARCHAR(255),
  PRIMARY KEY(id)
);
CREATE TABLE tag (
  id INT,
  blog_id INT,
  name VARCHAR(100),
  PRIMARY KEY(id),
  FOREIGN KEY (blog_id) REFERENCES blog(id)
);

generateConfig.xmlのtableにtagテーブルも追加して、"Generate"!ってやってみたら、Tag関連のファイルは生成されましたらが、参照関係についてのフィールドなどは全然生成されなかったです。本来であれば、Blog.getTags()みたいなメソッドが追加されてList<Blog>を取得できるようなコード生成してくれることを期待したのですが、外部キーの生成は自動的にやってくれないらしいですね。これは手動でやるとMapperなどの修正も必要なので結構めんどくさく、非常に残念。。
こちらのフォーラムにも同様の記事がありました。。。これもまたプラグインを使って作ってみるしかなさそうですね。。

これらMyBatis Generatorの詳細はこちらのチュートリアルを参照ください。

オープンソースORMのMyBatis(旧iBATIS)を使う

オープンソースのORM(Object-Relational Mapping)で、結構日本では利用されているiBATISの後継であるMyBatisについて触ってみました。

MyBatisはiBATISがApacheファンデーションからスピンアウトして新しくフォークされたiBATISの後継フレームワークであり、バージョンで言うとiBATIS3.0という位置づけらしいです。ライセンスはApache Licenseで自由かつ無償にて利用することができます。現在はGoogle Codeでソースコードが管理されているようです。
http://code.google.com/p/mybatis/

MyBatis/iBATISは、JPA(Java Persistence API)ベースのHibernateOracle Toplinkなどと比べ、SQL文を中心に作成していくということもあり、企業システムなどではSpringなどと組み合わせて多用されているようです。(ちなみにSpringは3.0以上をサポートしているらしいです。こちらを参照。Spring2.xであればiBATISを使う必要がありそうですね。)


ちなみに日本では上記のようなトレンドですが、全世界では下図のように圧倒的にHibernateの方が人気があるようです。

では早速試してみたいと思いますが、ここではEclipse4.2とMySQLデータベースをあらかじめインストールされている前提で進めていきたいと思います。ちなみにデータベースとテーブルはシンプルすぎますが、以下のものを利用します。

CREATE DATABASE mydb;

CREATE TABLE blog (
  id INT NOT NULL,
  content VARCHAR(255)
);

MyBatisセットアップ
ここから"Core Framework"をダウンロードして、解凍します。

mybatis-x.x.x.jar(私は3.1.1を利用)とlibフォルダに入っているjarファイルをすべてEclipse上の自分で作成したプロジェクトにコピーしてビルドパスに設定します。さらにMySQLのJDBCドライバーであるConnector/Jをダウンロードして、同様にコピーしてビルドパスに設定します。
次にMyBatis設定ファイルであるmybatis-config.xmlファイルを作成します。このファイルはデータベースの基本的な接続情報と各Mapperファイル(単純に言えばSQL文の書かれているファイル)への外部リンクURLで構成されています。



  
    
      
      
        
        
        
        
      
      
    
  
  
    
  


コーディング
MyBatis設定ファイルで各Mapperファイルはmapperタグに外部ファイルとして指定します。通常は1テーブル(エンティティ)単位で作成することになると思います。そのblogテーブル(エンティティ)用のMapperファイルであるBlogMapper.xmlは以下のようにSQL文を書くことでBlogクラス(エンティティクラス)と紐付けます。


  
  
  
  
      insert into Blog (id, content) values (#{id}, #{content})
  
  
      delete from Blog;
  


このblogテーブル用のBlogクラスは以下のようになります。このクラスは通常のPOJOで書くことができます。
public class Blog {
 private int id;
 private String content;
 
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getContent() {
  return content;
 }
 public void setContent(String content) {
  this.content = content;
 }
 
 public Blog(int id, String content) {
  this.id = id;
  this.content = content;
 }
 
 public Blog() {
  super();
 }
}

以下はこれらBlogクラスとMapperファイルを利用してデータベースアクセスするサンプルで、mybatis-config.xmlとBlogMapper.xmlを読み込み、Blogクラス経由でblogテーブルにアクセスするコードです。


String resource ="mybatis-config.xml";
InputStream is = Resources.getResourceAsStream(resource);
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = sessionFactory.openSession();
// delete records
session.delete("deleteAllBlogs");

// insert records
session.insert("insertBlog", new Blog(0, "Test1"));
session.insert("insertBlog", new Blog(1, "Test2"));

// select records
Blog blog = (Blog) session.selectOne("selectBlog", 1); 
System.out.println(blog);  
for (Object v : session.selectList("selectAllBlogs")) {
 System.out.println((Blog) v);
}
session.close();


詳細は、こちらのチュートリアルを参照ください。

次回は、これらのテーブル情報からエンティティクラスやMapperファイル(クラス)を自動的に生成するMyBatis Generatorについて説明したいと思います。



2012年11月6日火曜日

JavaでiPhone/iPadアプリを開発できる「Codename One」

JavaでiPhone/iPad、Androidなどのモバイルアプリケーションを開発できるというツール「Codename One」が、JavaOne 2012で取り上げられていたみたいなので、ちょっと調べてみました。

これはCodename One社のオープンソースプロジェクトで、Javaで書いたコードが、iOSやAndroid、BlackBerryのネイティブコードに変換されて動作する無償のツールみたいです。ツールの中身は、GUI BuilderなどのUIを作るツール、エディタなどのIDE、シミュレータ、Javaフレームワークとそのネイティブコードへの変換ビルダーなどがあるみたいです。(ビルドは使い込んでいくと課金対象のようです。)



有名な類似製品としては、JavaScriptでコードを書くという違いはありますがAppceleratorのTitaniumですね。

また、Macを持っていないユーザ用(?)にクラウドでビルドして、iOS用のインストーラであるipaファイルを生成できるようです。ただ、FAQを見ると、App Storeに上げるときなどに必要と言っているので、結局必要かな。。。と思いきや、ここで始めて知ったのですが、MacinCloudというMacOSのクラウドがあるらしいですね。Mac持っていない人には使えるかも。

話はそれましたが、要はJavaを知っていれば、クロスプラットフォームで稼働するモバイルアプリケーションが作れるっていうツールらしい。昔、TitaniumはAndroid/iOS上で同じコードでちゃんと動かなかったという経験(私の実装が悪かったのかも。。)があるので、こちらには期待したいですね。

アプリ開発の流れ
EclipseかNetBeansで開発することになるようです。

新規プロジェクト作成をすると以下の3つのソースコードが生成されるようです。
  • StateMachineBase: GUI Builderで自動生成された画面のクラスです。このファイルは手動でいじらないようです。
  • StateMachine: StateMachineBaseを継承したクラスで、StateMachineBaseを操作するようなコードをここに書くようですね。例えば、GUI Builderで作ったボタンの押下イベント発生時の処理をメソッドとしてコーディングするとか、あるイベントが発生したときに、GUIのデータセットなどを行うとか、ほとんどの処理はここに書いていくことになりそうです。
  • Main: まぁ、メインですね。AndroidやiOSのフレームワーク同様、ライフサイクルを持っているようです。

ソースコードに加え、以下のようなリソースファイルも。
  • レイアウトデザイン/テーマ/イメージ
  • 国際化
  • データファイル
APIも充実していて、以下のようにセンサーなどのモバイル特有のものにもアクセスが可能です。

  • カメラ
  • GPS
  • ビデオ
  • ストレージ
  • ネットワーク
  • サーバプッシュ
  • メール/SMS/電話
  • JSON/XML
  • 地図 など

稼働確認するには独自のシミュレータで実行することもできますし、クラウド上でビルドして、ビルド完了すると、作成された.ipaファイルのURLをメールなどで受け取り、iPhone/iPadなどの実機でダウンロードして実行できるようです。(Androidのシミュレータは非常に遅いので、これは速いといいのですが。)

まだ、実際にはダウンロードして試していませんが、ネイティブコードに変換されることからPhoneGapなどのWebkitベースのツールより高速に動くと思いますし、Objective-Cはイマイチ慣れないので、作りたいアプリが思いついたら試してみたいと思います。

※若干気になる点はGalleryにApp Storeに公開されているアプリがなさそう。。。まぁ、これからですかね。


2012年10月23日火曜日

Google Cloud Messaging for Android(GCM)を試してみる

モバイルアプリも流行ってきたので、さらにサーバプッシュの必要性が高くなってくると思い、メンバーと一緒にいろいろ試していってみようと思います。(Google Cloud Messaging、Apple Push Notification Service、WebSocketなど)

まずは、Google Cloud Messaging for Android(以下GCM)について試してみました。(ちょっと前までは、C2DMと呼ばれていたものです。)

動作は以下の図のように、Androidデバイスからregister idというものを生成及び登録し、その後サーバなどから登録されたデバイスに対してプッシュすることで、メッセージをリアルタイムに通知するという単純なものです。



実装については、基本的にはこちらのページ通りにやっていけばできると思いますが、ポイントとハマったところをまとめていければと思っています。また、サーバサイドのプッシュをPHPでやっている記事は多いですが、チュートリアルにあるサーブレットでやっている人が少なそうなので、今回はJavaサーブレットを使ってみたいと思います。

環境
Apache Tomcat 7
Android 4.1

API KeyとSENDER ID取得
https://code.google.com/apis/consoleからAPI KeySENDER IDを取得します。簡単なので詳しくは、http://developer.android.com/guide/google/gcm/gs.htmlを参照ください。

サーブレット作成
まずは、サーバサイドの仕組みを作るため、プロジェクト(Eclipse for JavaEEを使った場合は、Dynamic Web Project)を作成します。

AndroidをEclipseで開発するために、Android Development Tools(ADT)pluginをインストールして、Android SDK Managerで「Extras」⇒「Google Cloud Messaging for Android」を選択しGCMをダウンロードします。そのダウンロードしたディレクトリの中のgcm/gcm-server/dist/gcm-server.jarをプロジェクトにコピーします。(WEB-INF/libなどへ)
ただ、このjarファイルだけですと、java.lang.ClassNotFoundExceptionが発生します。
java.lang.ClassNotFoundException: org.json.simple.parser.ParseException
これは、gcm/gcm-server/lib/json_simple-1.1.jarがないため発生してるようなので、同様にコピーします。


では、早速サーバサイドのコードですが、3つのサーブレットを作ることとします。1つはregister IDの登録、2つ目はregister IDの登録解除、最後はメッセージ送信。

①. register ID登録サーブレット
Androidから受け取ったregister IDを適当なデータベースなどに登録しておきます。ここはデータベースではなくてもファイルでもキャッシュでも何でもいいです。

②. register ID登録解除サーブレット
単純に①で登録したものを削除します。

③. メッセージ送信サーブレット(サーバからクライアントへプッシュ)
Message.Builder builder = new Message.Builder().delayWhileIdle(true);
builder.addData("message", "Hello"); // 送信するデータ
Message message = builder.build();

String myAppKey = <API Key>
List<String> devices =<①で登録されたregister IDのList<String>>
Sender sender = new Sender(myAppKey);
MulticastResult result = sender.sendNoRetry(message, devices);


これでdevicesに対して、メッセージを送信できます。しかし、メッセージ送信時に以下のエラーが発生しました・・・。

javax.net.ssl.SSLHandshakeException:
   sun.security.validator.ValidatorException: PKIX path building failed:
   sun.security.provider.certpath.SunCertPathBuilderException:
   unable to find valid certification path to requested target

Caused by: sun.security.validator.ValidatorException:
   PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
   unable to find valid certification path to requested target

Caused by: sun.security.provider.certpath.SunCertPathBuilderException:
   unable to find valid certification path to requested target

これはSSL通信を行うために証明書が必要みたいなので、jssecacertsファイルを作成し、$JAVA_HOME/lib/securityにコピーするで解決できました。(keytoolを使うのもいいですが、私は簡単そうだったのでInstallCert.javaを使いました。)

ちなみに以下のコマンドでjssecacertsファイルを作成。
> java InstallCert android.googleapis.com

Androidプロジェクト作成
Androidプロジェクトを作成し、上記でダウンロードしてきたgcm/gcm-client/dist/gcm.jarをAndroidプロジェクトにコピーします。

次にActivityとServiceを作成します。

AndroidManifest.xml

    <permission android:name="com.scratch.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
    <uses-permission android:name="com.scratch.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <application
        <activity
            android:name=".GCMActivity"
            android:configChanges="orientation|keyboardHidden"
            android:windowSoftInputMode="adjustPan" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver
                android:name="com.google.android.gcm.GCMBroadcastReceiver"
                android:permission="com.google.android.c2dm.permission.SEND" >
                <intent-filter>
                    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                    <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
                    <category android:name="com.scratch" />
                </intent-filter>
        </receiver>
        <service android:name=".GCMIntentService" />
    </application>

Serviceクラス(GCMIntentService)
package com.scratch;

import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.google.android.gcm.GCMBaseIntentService;

public class GCMIntentService extends GCMBaseIntentService {

        static String SENDER_ID = <SENDER ID>;
        final private String TAG = getClass().getName();

        @Override
        protected void onError(Context context, String regId) {
                Log.v(TAG, "error " + regId);
        }

        @Override
        protected void onMessage(Context context, Intent intent) {
                Log.v(TAG, "Received message");
                Log.v(TAG, intent.getStringExtra("message")); //サーバからプッシュされたデータの受け取り
        }

        @Override
        protected void onRegistered(Context context, String regId) {
                Log.v(TAG, "registered regId=" + regId);
                // ここでサーブレット①にリクエストしてregister idを登録。
        }

        @Override
        protected void onUnregistered(Context context, String regId) {
                Log.v(TAG, "unregistered " + regId);
                // ここでサーブレット②にリクエストしてregister idを削除。
        }

        public GCMIntentService() {
                super(SENDER_ID); // superでSENDER IDを指定するようです。
                Log.v(TAG, "create GCMIntentService()");
        }
}

Activityクラス(GCMActivity)
package com.scratch;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

import com.google.android.gcm.GCMRegistrar;

public class GCMActivity extends Activity {

        final private String TAG = getClass().getName();

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);

                // check if this device supports GCM.
                GCMRegistrar.checkDevice(this);

                // check if it's right manifest.
                GCMRegistrar.checkManifest(this);
                final String regId = GCMRegistrar.getRegistrationId(this);
                Log.v(TAG, "regId=" + regId);
                if (regId.equals("")) {
                       // GCMIntentService.onRegisteredがコールされる。
                       GCMRegistrar.register(this, GCMIntentService.SENDER_ID); 
                } else {
                        Log.v(TAG, "Already exists " + regId);
                }
        }
}

ちなみに、unregisterはをするにはGCMRegister.unregisterメソッドを使い、これが実行されるとGCMIntentService.onUnregisteredが呼ばれます。

これでAndroidでサーバプッシュができるはずです。一度お試しを!(詰まったらコメントください。)

次回は、AppleのApple Push Notification Service(APNS)についても試していこうと思います。

2012年10月15日月曜日

HTML5をサポートする「Project Avatar」

JavaOneで発表されているProject Avatarというものに興味があり、いろいろ調べてみました。

来年にリリース予定だそうですが、次のOracleのクラウド・デバイスに対してのクロスプラットフォームアプリケーションを開発するための解決策であるフレームワークだと思います。

Avatarは、HTML5をベースとしたクライアント・フレームワークです。これまでのWebシステムではサーバサイドでMVCを持ち、Viewを生成してクライアントに返していましたが、モバイルアプリケーションはオフラインなどでも実行できるようになる必要があるため、クライアント側にMVCを持ち、これまでとはアーキテクチャが異なってきます。

クライアントでMVCを持つことに加え、サーバサイドのModel(データベース)とクライアントのModelをバインドできるように、REST、JSON、WebSocketsなどがサポートされるようです。これを「Thin-Server Architecture (TSA)」と呼んでいるようです。

(以下はJavaOne 2012のプレゼン資料から抜粋)



今後のアーキテクチャは、マルチプラットフォームに対応できるアーキテクチャが求められてくるため、こういったものが流行っていくんではないかと思います。でも、ちょっと前にAdobe FlexやMicrosoft Silverlightでもこういったフレームワークが提供されていた気がするので、大きな目新しさは少ないかもしれないですね。


また、JavaOne 2012では開発ツールであるProject Easelというものが発表されました。これは、NetBeansのpluginとChromeのExtensionから構成されており、HTML5ベースのプロジェクトを作成してコーディングし、デバッグ時にブレークポイントやステップ実行などを行えるというものです。また、コーディングはクライアントサイド・サーバサイド共にロジックはJavaScriptで書くことができるようです。そのため、クライアントからサーバまでトータルでNetBeansで開発できるようです。

期待度が高いですが、CoffeeScriptDartJSXなどといろんなJavaScriptの代替の言語が出てきている今、JavaScriptに対する不足感があるのでいろんなものが出てきているんではないかと考えています。そのため、Project Easelも開発言語はエンジニアが多いJava(GWT(Google Web Toolkit)のようにJava→JavaScriptのようなものを提供。)でよかったんではないかと個人的には思います。