2011年1月30日日曜日

[Java]プライベートフィールドを更新する

UnitTestなどでprivateなフィールドをコードを修正せずに値を設定しようとした場合、publicなアクセッサメソッドを呼び出すか、リフレクションを利用するしかありません。
リフレクションを利用する場合、クラスの型情報を指定する必要がありますが、いちいち指定するのが面倒です。というとで、なかったら再起で呼び出すロジックを組んでみました。コードはこんな感じ。


/**
 * プライベート変数に値を設定します。
 *
 * @param obj インスタンス
 * @param fieldName 変数名
 * @param value 値
 */

public static void setPrivateField(Object obj, String fieldName,Object value) {

    setPrivateField(obj.getClass(), obj, fieldName, value);
}

/**
 * プライベートなstatic変数に値を設定します。
 * finalな変数はダメです。
 *
 * @param cls クラス
 * @param fieldName 変数名
 * @param value 値
 */

public static void setPrivateField(Class<?> cls, String fieldName,
        Object value) {

    setPrivateField(cls, null, fieldName, value);
}

/**
 * プライベートなstatic変数に値を設定します。
 * finalな変数はダメです。
 *
 * @param cls クラス
 * @param obj インスタンス
 * @param fieldName 変数名
 * @param value 値
 */

public static void setPrivateField(Class<?> cls, Object obj, String fieldName, Object value) {

    do {
        try {
            Field field = cls.getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(obj, value);
            break;
        } catch (NoSuchFieldException e) {
            // 親クラスからの取得にtry
            cls = cls.getSuperclass();
        } catch (Exception e) {
            // 例外
            e.printStackTrace();
            break;
        }
    } while (cls != null);

}

2011年1月26日水曜日

[Java]プライベートフィールドの値を取得する

privateなフィールドをコードを修正せずに取得しようとした場合、publicなアクセッサメソッドを呼び出すか、リフレクションを利用するしかありません。
リフレクションを利用する場合、クラスの型情報を指定する必要がありますが、いちいち指定するのが面倒です。というとで、なかったら再起で呼び出すロジックを組んでみました。コードはこんな感じ。

/**
 * プライベート変数の値を取得します。
 *
 * @param obj インスタンス
 * @param fieldName 変数名
 * @return 値
 */

public static Object getPrivateField(Object obj, String fieldName) {
    Object result = getPrivateField(obj.getClass(), obj, fieldName);
    return result;
}

/**
 * プライベートなstatic変数の値を取得します。
 *
 * @param cls クラス
 * @param fieldName 変数名
 * @return 値
 */

public static Object getPrivateField(Class<?> cls, String fieldName) {
    Object result = getPrivateField(cls, null, fieldName);
    return result;
}

/**
 * プライベート変数の値を取得します。
 *
 * @param cls クラス
 * @param obj インスタンス
 * @param fieldName 変数名
 * @return 値
 */

public static Object getPrivateField(Class<?> cls, Object obj,
        String fieldName) {
    Object result = null;

    do {
        try {
            Field field = cls.getDeclaredField(fieldName);
            field.setAccessible(true);
            result = field.get(obj);
            break;
        } catch (NoSuchFieldException e) {
            //親クラスからの取得にtry
            cls = cls.getSuperclass();
        } catch (Exception e) {
            //例外
            e.printStackTrace();
            break;
        }
    } while (cls != null);

    return result;
}

2011年1月20日木曜日

[Android]USBドライバ

Android端末をADBで接続する際、USB用のドライバが必要になります。
ということで、コレまで使ったことのあるドライバを備忘のためメモ。


;HTC Desire
%SingleAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C87
%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C87&MI_01

;HTC EV4
%SingleAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C8D
%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C8D&MI_01

;SHARP IS03
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_939C&MI_05
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_939A&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_939B&MI_01

;Xperia X10
%SingleAdbInterface% = USB_Install, USB\VID_0FCE&PID_D12E
%CompositeAdbInterface% = USB_Install, USB\VID_0FCE&PID_D12E&MI_01

;HTC Aria
%SingleAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C92
%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C92&MI_01

2011年1月14日金曜日

[Java]プライベートメソッドを呼び出す

UnitTestなどでprivateメソッドをコードを修正せずに実行しようとした場合、該当のprivateメソッドを使っているpublicなメソッドを呼び出すか、リフレクションを利用するしかありません。
リフレクションを利用する場合、クラスの型情報を指定する必要がありますが、いちいち指定するのが面倒です。というとで、なかったら再起で呼び出すロジックを組んでみました。コードはこんな感じ。

/**
 * プライベートメソッド(引数なし)を呼び出します。
 *
 * @param obj インスタンス
 * @param name メソッド名
 * @return 戻り値
 * @throws Throwable プライベートメソッドから発生した例外
 */

public static Object invoke(Object obj, String name) throws Throwable {

    Object result = invoke(obj, new Object[0], name, new Class[0]);
    return result;
}

/**
 * プライベートメソッドを呼び出します。
 *
 * @param obj インスタンス
 * @param args 引数
 * @param name メソッド名
 * @param parameterTypes 引数タイプ
 * @return 戻り値
 * @throws Throwable プライベートメソッドから発生した例外
 */

public static Object invoke(Object obj, Object[] args, String name,
        Class<?>[] parameterTypes) throws Throwable {

    Object result = invoke(obj.getClass(), obj, args, name, parameterTypes);
    return result;
}

/**
 * プライベートメソッドを呼び出します。
 *
 * @param cls クラス
 * @param objインスタンス
 * @param args 引数
 * @param name メソッド名
 * @param parameterTypes 引数タイプ
 * @return 戻り値
 * @throws Throwable プライベートメソッドから発生した例外
 */

public static Object invoke(Class<?> cls, Object obj, Object[] args, String name, Class<?>[] parameterTypes) throws Throwable {

    Object result = null;

    do{
        try {
            Method method = cls.getDeclaredMethod(name, parameterTypes);
            method.setAccessible(true);

            result = method.invoke(obj, args);
            break;

        } catch (NoSuchMethodException e) {
            //親クラスの型でリトライ
            cls = cls.getSuperclass();
        } catch (InvocationTargetException e) {
            throw e.getCause();
        } catch (Throwable e) {
            e.printStackTrace();
            break;
        }
    }while(cls != null);

    return result;
}

2011年1月13日木曜日

[Android]SDKをバージョンアップしたら便利になった!

先日、AndroidのSDKを最新(ver8)にしました。ADTも0.99→8.0にしています。
以下のような変化がありました。

■ライブラリプロジェクトにのプロジェクト名に「-」をつけても大丈夫
 以前はライブラリプロジェクトを参照する側がエラーになっていました。

■ライブラリプロジェクトにnativeライブラリを置いておくと参照側のプロジェクトのapkに反映される
 以前はコピーする必要がありました。

■android.jarへのソース添付が簡単に
 以前は指定ができず、変わったやり方で指定する必要がありましたが、今は他のjarと同じ設定方法でできるようになりました。

■ADTのlogcatビュー
 スタックトレースのダブルクリックでコードにジャンプするようになった。以前はgoto problemをメニュー?から選択する必要があった

2010年12月7日火曜日

[Android]コンテンツのアイデア

私はバイクに乗ります。そしてひどく方向音痴な上に貧乏です。
一方Android系スマートフォンには、ほとんどGPSが搭載されています。そして画面が大きい。
ということで、以下のようなコンテンツを開発しようかと考えています。

  • 事前に大雑把な地図をダウンロードしておく
  • 現在どこいらへんにいるかをポイントして表示する
  • 家がどっちの方向にあるかを表示する

です。以前、一人でぶらりと大阪方面に出かけたことがあったんですが、いざ帰ろう。と思ったときに家がどっちのほうにあるのかさっぱりわからなくなってしまって。。。
ライセンスの問題があるかも知れませんが、地図はとりあえずGoogleさんから失敬して、緯度経度のマトリックスから、それらしい画像を選び、その上に現在地および家のある方向を指す。的なアプリケーションっでどうかなぁと。

地図の精度は、大きな国道および、高速道路・有料道路が若干わかる位のレベルでいこうかと思っています。イメージ的には、高速道路でもらえるレベルの地図の範囲でしょうか。

・・・と思っていたんですが、検索してみると同様のソフトがすでにあるんですね。MapDroydとか。。。

2010年11月9日火曜日

[Android]SDKのインストール

AndoroidのSDKをダウンロードし、Installed PackegesでUpdate All..を実施しました。
コレやらないと新しいバージョンの開発環境がそろわないので。
で、やってみると、↓のようなメッセージが。。。

「HTTPS SSL error. You might want to force download through HTTP in the settings.」

は?、会社ではこんなメッセージ出なかったのに。。。
で調べてみると、[Setting]→「Force https://... sources・・・」のチェックをオンに。
するとダウンロードが始まりました。

OSの違いか通信環境の違いなのか。。。ブラウザで見るとXML自体は表示できるのに。何なんだろう?