タグ「IT本」が付けられているもの

Android 入門本 の 私的レビュー

すこし事情があって、自分が購入し、参考にしている Android 関連書籍についてレビューを書こうと思います。

まず、前提としてどのような視点から見ているのかを明確にするために、自分自身のJavaのスキルと経験をカミングアウトしておきます。

Java 関連 保有資格(今は、OCJ-P なんですね。当たり前ですが)

  • SJC-P 1.4 (Sun Certified Programmer For The Java 2 Platform 1.4)
  • SJC-P 5.0 (Sun Certified Programmer For The Java 2 Platform 5.0)
  • SCWCD 1.4 (Sun Certified Web Component Developer For The Java 2 Enterprise Edition 1.4)

Java 関連 業務経験(10年程度)

10年ほど前に、よくわからずにEJBを使ったシステムに携わったのち、Swingを利用したC/Sシステムに少々絡んで、Strutsを使ったシステム、Java のバッチ、J2EE のシステム、と基本的には枯れたServer 側での仕事をしています(ました)。

ということで、Java に関して、まぁ教科書レベルの一通りの知識はあるが、クライアントJava プログラミング(Swing とか、並行性とか) はよくわからなくて、J2EE の Servlet、JSP の基本的知識と、古い フレームワークの経験がある程度の知識の人間が、Android に興味をもって勉強を始めようという立ち位置からのレビューです。

※★印は、Android 入門書籍として、自分に役に立った度です。

Google Androidアプリケーション開発入門 画面作成からデバイス制御まで――基本機能の全容

★★★★★

最初に購入した本

最初の20ページ程を使って、Android の概要、開発機と実行機が異なるクロス開発とはどういうものか、JDK、Eclipseの導入、Android SDKのインストール方法、エミュレーターの使用方法などが端的に説明されています。

それぞれ、詳細な手順が記されているわけではないです。しかし、書籍は Webと違って紙数が限られているので、まず、「概念」の理解に重点を置き、実際の手順は Web を参照すべし、という本書の方式は自分には合います。

開発についての章にも、その思想は現れています。

アクティビティ、インテント、リソース、ビュー、レイアウト、サービス、ノーティフィケーション、コンテンツブロバイダ・・・ と、Android 開発に登場する「概念」がわかりやすく説明されているため、全体像や、構成する要素を概観するには良いテキストだと思います。

詳細はリファレンスなりを参照すればいいわけですから、入門書に求められるのは、まさに新しい「概念」をわかりやすく説明することにあると考えると、その責は果たしています。

また、付随するサンプルソースも、基本的に動くサンプルソースなのですが、本質的ではない部分は簡潔に記述されおり、なるべく本質がわかりやすくなるように考えられていると思います。

サンプルは、センサーの取り扱いや、Google Maps の利用、位置情報、バーコードリーダー、カメラなど、携帯端末ならではのトピックも充実しています。

まぁ、上記で述べた本書の良い点は、逆に言うと、Java も Android も初めてのような初心者のためには説明が足りなくよくわからないし、具体的な実装方法のTipsや、そのまま動く教材のようなサンプルが欲しいような人には物足りない、といったことになるかもしれませんが、それは致し方ないでしょう。逆に自分はそこまで手取足取りではない方がうれしい。

 

全体として、Anroid 開発の始め方から、アプリケーションの公開まで、また、センサーやGoogle Maps、バーコードリーダーなどのキャッチーなサンプルコードを含みつつ、Android 特有の「概念」をわかりやすく網羅的に説明した良書 だと思います。

 

Android2.1プログラミングバイブル

 

★★★★☆

上記、Google Androidアプリケーション開発入門 の次に購入しました。なので、Anroid 開発の概要については、ある程度理解した上で読んでいます。

プログラミングバイブルと銘打つだけあって、かなりプログラミングにフォーカスした内容になっています。

Android の ユーザーインターフェースは、XML にて定義することができ、非常に便利なのですが、もちろん、Swing や AWT のように、Java のソースコードで構築することもできます。

で、本書は基本的にプログラミングにフォーカスしているからか、XMLによるレイアウト設定は使わずに、プログラミングによりユーザーインターフェースを構築するスタイルをとっています。

これは、これで、プログラムがどう動くのかを理解するには非常に良いのでしょうが、サンプルコードがすこし「うるさく」なる気もしないではないです。

要するに、自分は、欲しい部分のサンプルコードに対して、GUI の構築部分のソースコードなどは雑音に感じてしまう。

ただ、本書のサンプルアプリケーションを「そのまま」実装して教材として試してみたい場合、には必要なコードだと思います。そういう意味では、親切な設計になっています。

一応XMLレイアウトについても、数ページ触れられてはいますが、

「本書のサンプルプログラムでは、ユーザーインターフェースのレイアウトをJava言語で作成していますが、レイアウト情報をXMLで記述した『レイアウトファイル』をリソースとして利用することもできます。

とのことなので、著者は、基本的にGUIをプログラミングするスタイルなのでしょう。

自分としては、XMLでレイアウトできるところはXMLを利用したいですが、コードでの書き方も知っておくべきではあると思うので、そういう意味では良いと思います。ただ、この本のみを参照し、GUIの構築はこういうスタイルでやるべきだという先入観を持ってしまうのはどうかなと思うのは気にしすぎでしょうか。

内容は濃いと思います。また、API のリファレンスの抜粋が記載されているので、基本的な利用法であれば、いちいち、オンラインのリファレンスを参照する必要がない作りになっています。

あと、ところどころに、Java の文法のコラムがあるのですが、

「drawText() メソッドに渡している『"Hello World!"』は文字列です。Java 言語では『"』で囲んだ文字列がString型の文字列オブジェクトとなります。」

・・・ うーん。どのレベルの読者を想定しているのか微妙です。

 

全体として、端末の紹介から、SDKのAPIリファレンス、Java の文法コラムまで 総花的な内容をねらいつつも、親切な記述にはなっています。

サンプルコードのスタイル等に、著者の趣味が色濃くでている気がするのですが、これは好き嫌いですかね。

内容は豊富ですし、説明も丁寧なので、役に立つおもしろい本だと思います。

 

Android Hacks ―プロが教えるテクニック & ツール

★★★☆☆

この本は、確かに、テクニック & ツール ですね。

ただし、それぞれの テクニック について、懇切丁寧に説明したり、実際に動くサンプルコードが提供されることはありません。基本、それぞれについて、数ページを割いて、基本的な概念説明、基本的なコード、一歩進んだHACKの仕方という構成となっています。

紙数の都合もあるでしょうが、あえてすべてを提示しないことで、足りない部分を埋めるエクササイズを読者に強いているのではないかと思える節もあります

手取足取りの記述を好む方は、いらだつかもしれませんが、個人的には好感が持てるスタイルです。

どれも、読み物として(?)おもしろく読めますし、実際に何か機能を実現使用としたときに、どうしていいかのとっかかりを調べるのには良いと思います。

また、実機デバッグの仕方や、ADB や TraceView の利用法など、デバッグ手法についての記述があるのは、実際に開発を行う上で非常に役立つかと思います。

NDK(ネイティブコード環境)の記述、JNIの使い方、Android のソースコードをコンパイルして実機に焼く、など Hacks の面目躍如てきな項目もあるのですが、自分自身そこまで行けてないので、読み物として読むにとどまっています。

 

マニアックなおもしろい本だと思います。が、なぜか、全体を通して焦点が定まらない印象を受けました。テクニック & ツール ですし、一章が独立完結していて、どこからでも読める形式になっているので、それは、当然なのですけれど、他のO'Reilly 本にある、凝縮感が少し足りないというか・・・ まぁ贅沢な希望です。

 

Android Application Development

android market

★★★★☆

最後に、今、Android Market を確認したら、なくなってしまって(?)いましたが、Android Market にて、O'Reilly の本アプリが、あったので購入しました。

英語の本ですし、まだ読了していませんが、サンプルコードも充実しており、役に立ちます。

何よりすばらしいのは、価格が破格の安さです。500円程度。

ブックマークをつけることができたり、目次から各章へジャンプできたりと、情報を探すための機能も充実しています。

どうせ、込み入った情報を得ようとすると、英語のサイトにたどりつかざるを得ないので原書であることは英語の勉強と割り切るとして、価格を考えれば非常にお買い得だと思います。

 

今のところ、自分はAndroid行き詰まったら、http://goosh.org/ で、how to use surfaceview? などと打ち込んで、stackoverflow の投稿に行き当たり、それで解決することが多いのですが、本書に一通り、ざっと目を通したところ、 HACKS の名の通り、「あの機能はどうやって実現するのだろう?」と気になったときに役に立ちそうなTIPSが満載となっています。

さっそく、「HACK #113 設定画面を簡単に作成する」 の力を借りる日がやってきました。

これをみてちゃっちゃと設定画面を実装しましょう。

android_preferences01

上記の様な画面を簡単に作成できるはず。

・・・ だったんですが、

android_preferences02

デフォルトで提供されている設定用のUIコンポーネントは、以下ぐらいらしく、上記例のような、SeekBar を利用する設定画面は、そこまで簡単には作成できないようで。。。できても良さそうなのに。。。

UI部品 内容
CheckBoxPreference チェックボックス
EditTextPreference テキストボックス
ListPreference ラジオボタンのリスト

RingtonePreference

着信音リスト

 

もう少し時間をかけて考える必要がありました。

結果、以下の様に、実装し、ほぼほぼ動いているので、手順をメモします。

基本的には、

  1. Preference クラスの作成
  2. Preference クラス用のレイアウトの作成
  3. PreferenceActivity 用 レイアウトの作成
  4. PreferenceActivity の作成

となります。

 

SeekBarPreference クラスの作成

まず、設定画面用のActivity である、PreferenceActivity にて使用する、UI部品である、Preference クラスを継承して、SeekBar を使った設定用部品を作成します。

レイアウトは、後で記述しますが、コンストラクタで XML(/res/layout/preference_widget_seekbar.xml) を読み込みます。

Log を出力したところ、以下の順でメソッドが呼ばれるようです。

  1. onGetDefaultValue  デフォルト値読み込み
  2. onSetInitialValue 初期値を設定
  3. onBindView ビューとデータをバインド
 package info.typea.shujiroid.core;
 
 import info.typea.shujiroid.free.R;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.preference.Preference;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.SeekBar;
 import android.widget.SeekBar.OnSeekBarChangeListener;
 
 /**
  * @author piroto
  */
 public class SeekBarPreference extends Preference implements OnSeekBarChangeListener {
 
     private static final int MAX_PROGRESS = 100;
     private static final int DEFAULT_PROGRESS = 50; 
     private int currentProgress;
     private int oldProgress;
     
     public SeekBarPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
         setWidgetLayoutResource(R.layout.preference_widget_seekbar);
     }
     
     /* 
      * Preference が 呼び出されるときにデフォルト値が読み込まれる必要がある
      * 異なる Preference 型は異なる 値型 は持つはずなので、サブクラスはそれにあわせた型を返す必要がある
      */
     @Override
     protected Object onGetDefaultValue(TypedArray a, int index) {
         return a.getInteger(index, DEFAULT_PROGRESS);
     }
 
     /* 
      * Preference の初期値を設定する
      * restorePersistedValue が true の場合、Preference 値を、SharedPreference からレストアすべき
      * false の場合 Preference 値にデフォルト値をセット
      * (SharedPreference の shouldPersist() が true の場合、可能ならSharedPreferenceに値を格納) 
      */
     @Override
     protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
         if (restorePersistedValue) {
             currentProgress = getPersistedInt(currentProgress);
         } else {
             currentProgress = (Integer) defaultValue;
             persistInt(currentProgress);
         }
         oldProgress = currentProgress;
     }
 
     /*
      * Preference のために、ビューとデータをバインドする
      * レイアウトからカスタムビューを参照しプロパティを設定するのに適する
      * スーパークラスの実装の呼び出しを確実に行うこと
      */
     @Override
     protected void onBindView(View view) {
         final SeekBar seekbar = (SeekBar) view.findViewById(R.id.pref_seekbar);
         if (seekbar != null) {
             seekbar.setProgress(currentProgress);
             seekbar.setMax(MAX_PROGRESS);
             seekbar.setOnSeekBarChangeListener(this);
         }
         super.onBindView(view);
     }
 
     @Override
     public void onStartTrackingTouch(SeekBar seekbar) {}
     @Override
     public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) {}
     
     @Override
     public void onStopTrackingTouch(SeekBar seekbar) {
         int progress = seekbar.getProgress();
         /* ユーザーが設定変更を行った後(内部的な値を設定する前)に呼び出す。 */
         currentProgress = (callChangeListener(progress))?progress:oldProgress;
 
         persistInt(currentProgress);
         oldProgress = currentProgress;
     }
 }

SeekBarPreference UI 部品のレイアウトを定義(/res/layout/preference_widget_seekbar.xml)

今回 SeekBar のみで構成しましたが、通常の画面を作るように複数のコンポーネントを組み合わせることも出来そうです。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/LinearLayout01" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" >
    <SeekBar android:id="@+id/pref_seekbar" 
             android:layout_width="wrap_content" 
             android:layout_height="wrap_content"
             xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="100sp">
    </SeekBar>
</LinearLayout>

 

PreferenceActivity のレイアウト&定義(/res/xml/preferences.xml) を作成

設定画面のレイアウト XML を作成します。通常の画面レイアウトとは、置き場所や書き方が異なります。このあたりの詳細は、上記 Android Hacks ―プロが教えるテクニック & ツール を確認ください。

以下は、上記例の設定用XMLとなります。

android:key の値にて、SharedPreference から 設定値を取得することができる様になります。

問題の、SeekBarPreference の利用法は、info.typea.shujiroid.core.SeekBarPreference 要素を参照。

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
        xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory
            android:title="@string/lbl_brush_pref_title">
        <info.typea.shujiroid.core.SeekBarPreference
                android:key="calligraphy_diameter"
                android:title="@string/lbl_diameter_of_brush"
                android:summary="@string/lbl_diameter_of_brush_summary"
                android:defaultValue="50"/>

        <info.typea.shujiroid.core.SeekBarPreference
                android:key="calligraphy_smoothness"
                android:title="@string/lbl_smoothness_of_brush"
                android:summary="@string/lbl_smoothness_of_brush_summary"
                android:defaultValue="50"/>

        <info.typea.shujiroid.core.SeekBarPreference
                android:key="calligraphy_alpha"
                android:title="@string/lbl_alpha_of_brush"
                android:summary="@string/lbl_alpha_of_brush_summary"
                android:defaultValue="50"/>

        <CheckBoxPreference
                android:key="calligraphy_antialias"
                android:title="@string/lbl_antialias"
                android:summary="@string/lbl_antialias_summary" />
        <ListPreference 
                android:key="calligraphy_color"
                android:title="@string/lbl_brush_color"
                android:summary="@string/lbl_brush_color_summary"
                android:entries="@array/ary_colors" 
                android:entryValues="@array/ary_color_values" />
        <ListPreference 
                android:key="calligraphy_background_color"
                android:title="@string/lbl_background_color"
                android:summary="@string/lbl_background_color_summary"
                android:entries="@array/ary_colors" 
                android:entryValues="@array/ary_color_values" />
        <CheckBoxPreference
                android:key="shujiview_vibrate"
                android:title="@string/lbl_vibrate"
                android:summary="@string/lbl_vibrate_summary" />
   </PreferenceCategory>
</PreferenceScreen>

設定画面(PreferenceActivity) の作成

res/xml/preferences.xml で定義した、Preference (設定項目のUIコンポーネント) から値を設定、取得するためのキーを、設定画面呼び出し元のActivity から参照できる様に定数化していますが、それ以外は何もしてません。PreferenceActivity を継承して自分のアプリケーション用の Activity を作成し、addPreferencesFromResource を利用して、設定ファイルを参照するだけです。

package info.typea.shujiroid.core;

import info.typea.shujiroid.free.R;
import android.os.Bundle;
import android.preference.PreferenceActivity;

public class ShujiPreferenceActivity extends PreferenceActivity {
    public static final String KEY_CALLIGRAPYHY_DIAMETER         = "calligraphy_diameter";
    public static final String KEY_CALLIGRAPYHY_SMOOTH           = "calligraphy_smoothness";
    public static final String KEY_CALLIGRAPYHY_ALPAH            = "calligraphy_alpha";
    public static final String KEY_CALLIGRAPYHY_ANTIALIAS        = "calligraphy_antialias";
    public static final String KEY_CALLIGRAPYHY_COLOR            = "calligraphy_color";
    public static final String KEY_CALLIGRAPYHY_BACKGROUNDCOLOR  = "calligraphy_background_color";
    public static final String KEY_SHUJIVIEW_VIBRATE             = "shujiview_vibrate";
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
    }
}

設定を利用する

これで、設定画面が完成しました。メインのアクティビティから利用してみます。

設定画面を呼び出す

任意の値(ここでは、REQUEST_CODE_PREFERENCS としました)を指定して、startActivityForResult を呼び出す。

private static final int REQUEST_CODE_PREFERENCES = 1;
   :
startActivityForResult(new Intent(this, ShujiPreferenceActivity.class),REQUEST_CODE_PREFERENCES);

設定画面を閉じる

設定画面を閉じると、onActivityResult が呼ばれるので、これをオーバーライドします。

先ほど設定した任意のコードが否かを requestCode で判定して、同一なら、SharedPrerferences から、設定値を取得します。

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_PREFERENCES) {

        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
        
        int diameter = pref.getInt(ShujiPreferenceActivity.KEY_CALLIGRAPYHY_DIAMETER, 50);
        int smooth   = pref.getInt(ShujiPreferenceActivity.KEY_CALLIGRAPYHY_SMOOTH, 50);
                          :
    }
}

以上の手順で、カスタムPreference を利用した設定画面を作成することが出来ます。

最後の詰めを考えさせる作りになっているあたり、さすが ANDROID HACKS という気もします。

また一歩野望に近づいた!

最近は、なかなかなかなか入荷しない、Desire を待ちながら、Android アプリのサンプルをしこしこ試しています。

いまのところ、「Google Androidアプリケーション開発入門 画面作成からデバイス制御まで――基本機能の全容」 を教科書としています。

基本的には、ネット上のリファレンスやサンプルで事足りるはずなのですが、
新しい概念を母国語以外(英語)で十分に理解するには自分の語学力では時間がかかるので、本書を手に取りました。
著者の後書きにもあるとおり、 著者も同じ問題を経験して本書を執筆しているからか、
Android独自の概念が非常にわかりやすく説明されています。

英語のドキュメントを読んでいるだけだと、自分の読解力では、Intent あたりの理解に自信が持てなかったのですが、明確に理解できました。

サンプルのコードは、本質の処理がそうでない処理に埋もれてしまうというような複雑さはないし、欲しいところがないということもなく、過不足なく、つぼを押さえた形になっていると思います。

訳書にあるような持って回った言い回しがなく簡潔に書かれているため、
一見内容が少ないように見えます。
実際ながし読みならすぐに読み終わってしまいますが、サンプルを実際にコーディングしながら読み進むと、
非常にバランスのよい良書であると感じています。

約 500 ページ と結構ページ数はあるが、概念的な説明に必要以上にページ数を割くこともなく、「開発のプロが教える」とうたうだけあり、Django の使用法等、実用に重点が置かれた記述となっているため意外と読み進めやすい。

Django の書籍を購入しようとすると、本書を含めかなり選択肢が限られるが、果たして Django で何ができるのか、 Dango をどう使うのかという疑問は本書に大きく目を通せば解決するだろう。逆にいえば、事例を含めそのあたりを説明しようとすると、500ページくらいは必要なのかもしれない。別途購入した別のハンドブック形式一冊は、詰め込みすぎのためか、全体像をつかみたいという要求を満たしてくれなかったが、本書ではそんなことはない。

実務的な良書であるが、逆に、そのあたりが物足りなくもある。もう少し Django の哲学、思想、歴史に踏み込まれていると手引書を超えた一冊になるのだが。贅沢な希望か。

初めてのPython

「初めての」と銘打たれてはいるが、768ページという厚さの本書が持つ内容は、「読み終えればPythonプログラマであると名乗る資格がある」と著者が言うように非常に濃いものとなっている。JavaでのSJC-P対策本的な内容に近いといえば、分かりやすいだろうか? Pythonをただ使ってみるだけの本ではない。

言語のコアな部分については、用例、動作の理屈から陥りやすい罠、3.0ではどうなるのかまで含めて丁寧に解説されている。若干まわりくどかったり、説明的すぎたり、関連する概念が一度に説明されずに、後の方の章にでてきたりと、読みにくく感じる部分もあるが、著者が初学者へ行った講義が本書のベースになっているため、これらの特徴は、聴講者に理解させる著者の講義手法を本書でも採用したためなのだろう。とはいっても、実際に講義である訳ではないので、自分が理解している箇所は読み飛ばせばよいし、また、理解していない箇所はその「説明的すぎる」書き方のおかげで、著者のねらいどおり、理解を非常に助けてくれる。そのため、初めて出会うような概念でも本書だけで理解が可能となっている。読者の理解度にばらつきがあるを前提とすれば、一見無駄が多いように見えたとしても結果的には良いスタイルだと思う。

Python チュートリアル

Python 実行環境のヘルプに英文が含まれているし、日本語訳もWebで公開されている

にもかかわらず、価格が4千円もしたならば買わないけど、1200円。

他の言語を何がしかマスターしていて、Pythonでの表現を手っ取り早く知りたい、また、Python独特の概念を知りたいと考える向きには出しても惜しくない金額だと思う。自分的には、Webから印刷の手間 + インク代 > 本書代金。 電車で読めるし、手元に置いておける。

ページ数は薄いのだが、非常に簡潔にPythonの特徴が説明されており、一読すればすんなりとPythonの世界へ入っていける。

ただ、懇切丁寧な説明があるわけではないので、いきなりの入門者には敷居が高いかも。

マスタリング JavaEE5

マスタリング JavaEE5 なる本を読んだ。

かゆいところに手が届いているというか、粒度が適切というか、非常にバランスが良い本。

JavaEE5の全体像を概観しつつも、導入方法や、画面のキャプチャ等で紙数を浪費することもなければ、マニュアル的な、すべて読んでいては全体を見失ってしまうような細かさでもなく、なんというか物語性すらある。

金額も約5,000円と決してお安くはないので、まったくの初心者は手を出さないだろうし、エキスパートはネットから英語の資料を探すだろうから、「必要に応じてマニュアルを読むことはいとわないが、まずは全体像をある程度具体的に捉えたい」といった要求を持つ読者層に絞り込めているからなのかな。といっても、実践にもつかえるだけの内容は確保されており、そのあたりのさじ加減が絶妙だと思う。

また、JavaEEの技術紹介というだけでなく、システム的に重要な概念について丁寧に説明されている。たとえば、アイソレーションレベル等、トランザクション管理について非常に分かり易く書かれており感銘を受けた。いままで読んだデータベース関連の書籍に比べても抜けて分かり易い。トランザクションが開始されていれば、すべての不整合が発生しないと純粋無垢に考えている技術者の方も意外と多く、是非その章だけでも読んでほしいと思う。議論がかみ合わないんだよな~ほんと(愚痴です)。

著者が日本人ということもあり、この手の本の翻訳本にありがちなアメリカンジョークに行数を割かれていないのもよい。かも。

初めてのJavaScript

初めての「プログラミング言語が」JavaScriptな方には確かに不向きだし、またレファレンス的なものを求める方には中途半端かも知れません。
逆に言うと、別の言語をマスターしていて、JavaScriptの骨格を掴み取りたい方、斜め読みしたい方には非常によい本です。
また、JavaScriptに関する、ネット上で得られる断片的な知識などを肉付けする、骨格となるべき知識は得られる本だと思います。