Androidアプリケーションフレームワークを改造してPCRescuroidを追加する実践しながら学ぶ Android USBガジェットの仕組み(10)(2/2 ページ)

» 2013年03月08日 10時00分 公開
[村上雅彦、舟元拓斗、森崇(永和システムマネジメント),MONOist]
前のページへ 1|2       

3.PCRescuroidの設計とプログラム構成

3.1.PCRescuroidの設計と実装内容

 PCRescuroidの設計は、以下の2つの層に分けて行います。


分類 内容
アプリ層 一般的なAndroidアプリとして実現する機能
フレームワーク依存処理層 フレームワーク内の非公開APIを呼び出す機能
表4 2つの層に分けて設計

 本稿では、フレームワーク依存処理層について、その設計概要を紹介します。

 フレームワーク内の非公開APIの呼び出しは、先述の通り、リフレクションを使用することにしました。とはいえ、アプリの実装内に、リフレクションのためのソースコードを記述していくのは骨が折れますし、アプリとフレームワーク依存部分との境界が見えにくくなり、結果的に保守性の悪いソースコードが出来上がることになります。

 そこで今回、アプリ層とフレームワーク依存処理層の境界をしっかりと分けるために、図3のような設計としました。

PCRescuroidの設計 図3 PCRescuroidの設計【※画像クリックで拡大表示】

 本設計では、フレームワーク依存処理層のインタフェース(MountService)を定義し、PCRescuroidのアプリは、このインタフェースを通してAndroidアプリケーションフレームワーク層の処理を呼び出すことにしています。

 インタフェース実装部分については、一般的に、個々のAPIに対応するリフレクション処理をインタフェース実装クラスで定義することになります。しかし、今回は、Javaに標準で組み込まれているProxyクラスを使用することで実装コストを低減することにしました。

 Proxyクラスは、「インタフェース」と「実現方法」を分離し、それらをつなげる代理人としての機能を提供しています。Webサービスの呼び出しでよく見掛けるものですが、この場合の実現方法は、「ネットワーク越しのサービスを呼び出す」です。今回、「リフレクション処理でフレームワークの非公開APIを呼び出す」ことになるので、そのためのハンドラをProxyのnewInstance()メソッドに渡すだけで済みます。ハンドラの具体的な実装内容は以下の通りであり、2行のリフレクション処理だけで全てのMountServiceのインタフェースを実現できます。

クラス private static class MountServiceInvocationHandler implements InvocationHandler
メソッド public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
概要 引数で渡されてくるmethodとargsからMountServiceのメソッド呼び出しを行う
対象コード 以下、ソースコード1

//MountServiceのメソッドを取得する
//引数で渡されてくるmethodは、アプリが実行したMountServiceインタフェースのメソッドであり、
// MountService(フレームワーク)のメソッドと同じシグネチャである
Method serviceMethod = mountService.getClass().getMethod(method.getName(), method.getParameterTypes());
 
//取得したメソッドを実行する。引数には、MountServiceのオブジェクト(mountService※)とメソッド引数(args)を渡す
return serviceMethod.invoke(mountService, args);
//(※)mountServiceは、事前にServiceManagerを通して取得しておく
ソースコード1

3.2.Androidアプリケーションフレームワークの改造内容

 Androidアプリケーションフレームワーク層の改造内容は、先述の通り、MountServiceクラスのNotificationの設定として、タップ時に起動するアプリを「クラスオブジェクト(UsbStorageActivity)」から「クラス名の文字列(PCRescuroid)」に変更するだけです。以下に改造箇所を示します。

クラス MountService
メソッド void updateUsbMassStorageNotification(boolean suppressIfConnected, boolean sound)
概要 本メソッドは、MountServiceがUSBマスストレージの状態の変更を通知する場合に呼び出すものであり、タップ時に起動するアプリをPCRescuroidに変更する
対象コード 以下、ソースコード2

// 通知により起動するフレームワーク標準のcom.android.internal.app.UsbStorageActivityを
// PCRescuroidのjp.co.esm.etec.usbgadget.FormatChooseActivityに変更する
intent.setClassName(mContext, "jp.co.esm.etec.usbgadget.FormatChooseActivity");
ソースコード2

3.3.プログラム構成

 今回作成したPCRescuroidとAndroidアプリケーションフレームワーク層の改造部分のプログラム構成、および、その配置先を以下に示します(注4)。

アプリのプログラム配置場所
https://github.com/esminc/qemu/tree/master/PCRescuroid/src/jp/co/esm/etec/usbgadget

概要 対象ファイル
画面 初期画面 FormatChooseActivity.java
SDマウント画面 SDCardMounter.java
ISOマウント画面 ISOFileMounter.java
サービス選択画面 ServiceChooseActivity.java
CDイメージ検索画面 FileViewerActivity.java
コントローラ フレームワークとのインタフェース MountService.java
フレームワーク依存処理機能実装 MountServiceUtil.java

フレームワーク改造対象となるプログラムの配置場所
https://github.com/esminc/qemu/tree/master/android/platform_frameworks
/base/services/java/com/android/server

修正概要 対象ファイル
MountServiceのアプリ依存部分の改造 MountService.java

注4:設定ファイルは除きます。


4.おわり

 今回は、Androidアプリケーションフレームワークに強く依存するアプリの開発において、開発効率を向上させるための手法を紹介しました。

 以上で、PCRescuroidのアプリ側の開発はほぼ終了です。ただし、現時点では、ISOイメージファイルをマウントするためのドライバが、Androidカーネル内に存在しないため、全機能の実現には至っていません。そこで次回は、AndroidカーネルにCD-ROMドライバを追加するための方法を模索した結果を紹介したいと思います。ご期待ください! (次回に続く)


Android コーナー

Androidコーナー
「Android(アンドロイド)」の組み込み機器への適用からアプリ開発、レポート、ニュースなどさまざまな技術情報・最新動向をお届けする!!

>>コーナーTOPはこちらから


前のページへ 1|2       

Copyright © ITmedia, Inc. All Rights Reserved.