iPhoneアプリ開発1日目

更新するの久々w

更新を頻繁にしていた時は、Androidに関してに記事を色々と書いていました。
でも、HT-03持ってない。。。iPhone持ってるw


ってことで、iPhoneアプリも手を出してみようと思ってます。
っで、とりあえず開発環境はすでに整ってる(環境だけは入れてたw)

とりあえず、ここをで説明されている
アプリ作成しました。


Objective-cはやったことないけど、Web上のサンプル見ながらなら
なんとか書けるみたい。


さて、会社のRSSを閲覧、POSTできるアプリを作成するまで何日かかるかな〜
ただ、iPhoneのUI設計やクラス設計などが全く知識ないから
パフォーマンス悪くなるなるだろうな。。。
とりあえず、UIの作成はAndroidとは次元が違うくらい楽!
それだけで、嬉し恥ずかし土曜日。


今回は、いつまで続くかなwww

Log4jで複数プロセスから同一ファイルへの出力

ログ出力ライブラリでデファクトスタンダードLog4jですが、
複数プロセスからの同一ファイル書き込みの際、
ファイルロックの取り合いでローテションのタイミングなどで
ファイルが壊れたり、正常に書き込めなかったりと問題が満載です。


そんな時にやくに立つのが、SocketServerです。
Log4jのライブラリ内にSocketServerが存在します。
Log4jのものは使うなと良く噂に聞いていたのですが、ソースをきちんと
読んで判断したかったので実際に読んでみました*1


Log4j内には、「SocketServer」、「SimpleSocketServer」の2つが存在します。
以下はSimpleSocketSererのソース

  public static void main(String argv[]) {
    if(argv.length == 2) {
      init(argv[0], argv[1]);
    } else {
      usage("Wrong number of arguments.");
    }
    
    try {
      cat.info("Listening on port " + port);
      ServerSocket serverSocket = new ServerSocket(port);
      while(true) {
	cat.info("Waiting to accept a new client.");
	Socket socket = serverSocket.accept();
	cat.info("Connected to client at " + socket.getInetAddress());
	cat.info("Starting new socket node.");
	new Thread(new SocketNode(socket,
				  LogManager.getLoggerRepository())).start();
      }
    } catch(Exception e) {
      e.printStackTrace();
    }
  }


  static void  usage(String msg) {
    System.err.println(msg);
    System.err.println(
      "Usage: java " +SimpleSocketServer.class.getName() + " port configFile");
    System.exit(1);
  }

  static void init(String portStr, String configFile) {
    try {
      port = Integer.parseInt(portStr);
    } catch(java.lang.NumberFormatException e) {
      e.printStackTrace();
      usage("Could not interpret port number ["+ portStr +"].");
    }
   
    if(configFile.endsWith(".xml")) {
      DOMConfigurator.configure(configFile);
    } else {
      PropertyConfigurator.configure(configFile);
    }
  }
}

とまあ、待ち受けるサーバ側としてよく見る普通の形。
SocketServerの方も基本的には同じ。
Log4jなんで、設定ファイル読み込みなどがあるのが違いだけ。


ただ、ServerSocketのクローズ処理がないのが気になる・・・
さて、実際のログ出力処理は、

new Thread(new SocketNode(socket,
	  LogManager.getLoggerRepository())).start();

この部分。

SocketNodeは、以下のようなソース

public class SocketNode implements Runnable {

  Socket socket;
  LoggerRepository hierarchy;
  ObjectInputStream ois;

  static Logger logger = Logger.getLogger(SocketNode.class);

  public SocketNode(Socket socket, LoggerRepository hierarchy) {
    this.socket = socket;
    this.hierarchy = hierarchy;
    try {
      ois = new ObjectInputStream(
                         new BufferedInputStream(socket.getInputStream()));
    }
    catch(Exception e) {
      logger.error("Could not open ObjectInputStream to "+socket, e);
    }
  }

  public void run() {
    LoggingEvent event;
    Logger remoteLogger;

    try {
      if (ois != null) {
          while(true) {
	        // read an event from the wire
	        event = (LoggingEvent) ois.readObject();
	        // get a logger from the hierarchy. The name of the logger is taken to be the name contained in the event.
	        remoteLogger = hierarchy.getLogger(event.getLoggerName());
	        //event.logger = remoteLogger;
	        // apply the logger-level filter
	        if(event.getLevel().isGreaterOrEqual(remoteLogger.getEffectiveLevel())) {
	        // finally log the event as if was generated locally
	        remoteLogger.callAppenders(event);
	      }
        }
      }
    } catch(java.io.EOFException e) {
      logger.info("Caught java.io.EOFException closing conneciton.");
    } catch(java.net.SocketException e) {
      logger.info("Caught java.net.SocketException closing conneciton.");
    } catch(IOException e) {
      logger.info("Caught java.io.IOException: "+e);
      logger.info("Closing connection.");
    } catch(Exception e) {
      logger.error("Unexpected exception. Closing conneciton.", e);
    } finally {
      if (ois != null) {
         try {
            ois.close();
         } catch(Exception e) {
            logger.info("Could not close connection.", e);
         }
      }
      if (socket != null) {
        try {
          socket.close();
        } catch(IOException ex) {
        }
      }
    }
  }
}

さて、ここで気になるのがまたSocketのクローズ処理がないこと。
ちなみに、

      if (ois != null) {
          while(true) {
	        // read an event from the wire
	        event = (LoggingEvent) ois.readObject();
	        // get a logger from the hierarchy. The name of the logger is taken to be the name contained in the event.
	        remoteLogger = hierarchy.getLogger(event.getLoggerName());
	        //event.logger = remoteLogger;
	        // apply the logger-level filter
	        if(event.getLevel().isGreaterOrEqual(remoteLogger.getEffectiveLevel())) {
	        // finally log the event as if was generated locally
	        remoteLogger.callAppenders(event);
	      }
        }
      }

while(true)って無限ループ?
なんで・・・
CPU食いまくりなんじゃないかと思って、実際に動かしてみたら全然食わない・・・
色々とデバッグで動作を確認したら、
Log4jを使用しているクライアント側の最初の要求以降、通信はずっと開きっぱなし。
まあ、確かに通信接続切断を頻繁にしてたらコストがかかってしょうがないので。
ようは、下記部分で待つ。

event = (LoggingEvent) ois.readObject();

とれたら処理を繰り返す。
クローズ処理がないのは、クライアント側が終了したタイミングで通信が切られている。
なんで、クローズ処理をする必要がないってことで実装してないのかな!?
でも、普通は入れるよなww


とまあこんな感じでした。
少し手を加える程度で十分使えると感じました。
やはり自分で読んで確認してみるのが一番ですね。


ちなみに、クライアント側Log4jの設定ファイルでAppendarの数だけ個々にSocketを開くので
ご注意ください。

*1:log4j-1.2.15のソース

今更ながらBuildしてみる

さて、今更ですが自分でandroidをbuildして、
DevPhoneに入れてみました。
その時のメモ。

1.androidのソースを最新にする
以前にすでにgitはセットアップしてたので
最新にするだけ。


2.Androidメモを参考にbuild


順調に進んでたんですが、buildでエラーでました。

make: *** [out/target/common/docs/offline-sdk-timestamp] エラー 45

何それ?w
調べてみたら、JDKのバージョンによって出るみたい。
JDK6の64bit版はいかんらしい。
JDK5 32bitにしてもう一度Build。
小一時間ほど経過して、完了。

DevPhoneにインストール。
Localeに日本語選べる〜〜〜!!
うれしい!!









ん?






gmailなくなってる・・・
カレンダーも正常に起動しない・・・
なんで?


とりあえず、原因が不明なので戻しました。

docomoから発売発表!!


※CNETから画像引用してます
とうとう発表されましたね〜
やはりドコモからの発売でした。
ちなみに、HT-03Aのサイト→http://ht-03a.nttdocomo.co.jp/
見た感じ、QWERTYないのか〜。ソフトキーボードって慣れるまで
大変なんで、DevPhoneみたいにQWERTY(クワティー)搭載してほしい。
それに、2D、3Dがもう少し強くならないとiPhoneユーザーの取り込みは
難しい感じが・・・


でも、発売されると日本でもさらに盛り上がること間違いなし!
今から手を出しててよかった!!
開発に入りやすいもんな〜案件よ来い!参画したい!


ってアピールしましたが、発売発表されたんでそろそろ
仕事でも増え始めるかな?

SDK1.5にセキュリティーホール

昨日、AndroidのMLでSDK1.5にセキュリティーホールがあったと
流れてきた。
すでにパッチが配布されており、DevPhoneのイメージも配布されている。
パッチ適用済みSDK1.5r2も配布されているようです。


セキュリティーホールの内容→http://www.ocert.org/advisories/ocert-2009-006.html
DevPhoneのイメージ→http://www.htc.com/www/support/android/adp.html
パッチ適用済みSDK1.5r2→http://developer.android.com/sdk/RELEASENOTES.html#1.5_r2


とりあえず、DevPhoneも更新し、ローカルのSDKにもパッチ適用しました。
DevPhone持ってる方は、更新したほうが良いかと思います。
※更新方法は、4月28日のエントリーを参考にしてください。

エンジニアブログって・・・

私は色々な方の、いわゆるエンジニアのブログを毎日見ています。
ブログを見ていて、多く味あう違和感を2点今日は書きたいと思います。


1.簡単なコードはあまり記載しない
例えば、こういう事をしたという記事は良くみかけますが
その内容が非常に高度で難しいことが多い。
その前段階において、もっとシンプルで簡単をものがあるはず。
それを実は知りたいエンジニアは山のようにいるはず。



2.文章が難解
IT業界って略語が多いですよ。
これは、調べればいいだけなんで問題ないんですが
感想にしても思いを書いているにしても文章が難解。
本をよく読まれているかたなは、やはり語呂が抱負で
様々な言葉を使うことが出来る方が多いです。
ただ、読みやすい文章を書ける方ってのは少ない気がします。



まとめ
基本的に勉強不足と言われればおしまいですw
ブログって自分が好きなことを書くのでそんなことまで
気にしてられないってのが真実か・・・
ブログって個々にスタンスが違うので、あまり言えないですが
その他大勢が見てるっことを気にするか気にしないかで
かなり変わると思われるわけで。
読みやすい、理解しやすい文章ってのは難しいなと書いていて痛感しました。


※私的には、分かりやすい言葉で書いてるブログが好きなだけですw
※ブログのスタンスを批判するわけではありません
※そんなブログを参考にしてたりするのは内緒w


「分かりやすい文章」の技術―読み手を説得する18のテクニック (ブルーバックス)

「分かりやすい文章」の技術―読み手を説得する18のテクニック (ブルーバックス)

Dev Phoneを1.5にする

さて、本日Android SDK 1.5がリリースされました。
しかも、Dev PhoneのイメージもHTCのサポートからDownload出来る!
HTCの中の人、gj

早速、実機を1.5にupdateします。
前回は、radioイメージとsystemイメージを使ってupdateしましたが
今回は、リカバリーイメージでupdateしたいと思います。
なぜかって?楽だからw

1.DevPhoneをPCと接続
2.接続確認

trash$ adb devices
List of devices attached 
HT92RLZ00597	device

うん、接続OK


3.ダウンロードしたリカバリイメージを転送

trash$ adb push signed-dream_devphone-ota-147201.zip /sdcard/update.zip

この時に、「update.zip」にリネームして転送する。


4.リカバリモードで起動
DevPhoneを一度電源を切り、ホームボタン(家の絵のボタン)を押したまま起動
そうすると、!と携帯(?)の画像が表示されるかと思います。


5.アップデート実施
4の画像が表示されたら、queryキーボードを開いて、「Alt + l」を押す。
そうすると画面に、黄色い文字が色々出てきます。
文字が出てきたら、「Alt + s」を押します。
インストールが開始されるので、男は黙って静観。


6.イメージの書き込み
5が完了すると、下記メッセージが表示されます。

Press the HOME-BACK key combination to write the recovery image, update the firmware, and automatically reboot.

メッセージとおりに、「HOME + BACK」を押す。
少ししたら、書き込みだすので一度押したら不安にならずに画面をみてましょう。
あとは、自動でリブートもするので起動した完了です。

Firmwareが1.5になってるのを確認しましょう。


っで、1.5からは日本語に対応したはずなのでロケールを日本に設定します・・・

ん?English?のみ・・・
そうですか、DevPhoneはまだですか・・・


とりあえず、以上で完了です。