古いAndroidへの対応:「はじめてのAndoid5プログラミング」

このページは「はじめてのAndoid5プログラミング」(清水美樹著、工学社刊、2015年2月14日発売、 ISBN978-4-7775-1879-1)の著者によるの著者による関連情報です。

Androidの「新しい仕様」には、「古いAndroidに対応するようにするサポート・ライブラリ」も含まれます。SDKサンプルの多くがこのサポート・ライブラリを使って書かれています。 古いAndroidへの対応法と、新しいライブラリだけで書く方法を解説します。

本書の目次へ
このサイトのトップへ


古いAndroidへの対応、概要

「android.support.v?」というライブラリ

Android5.0の新仕様の代表ともいえる「CardView」「RecyclerView」 は「android.support.v7」で始まるパッケージのクラスです。「v7」は「Android2.1」の意味で、Android2.1用のアプリでもこの仕様を使うことができます。 このような「Android.support.v?」(?はAPIバージョン)というパッケージ名のライブラリは、Androidの各バージョンの標準APIとは別の「サポート・ライブラリ」です。 たとえば別ページで解説した

SDK添付サンプルのFloatingActionButtonBasic」では「com.android.support:support-v4:21.+」という サポート・ライブラリが導入されています。本書5-2節で行った通り「build.gradle(Module:Application)」と書かれているノードを開いて、 確かめてみましょう。

図1 「Gradle」スクリプトを開く
図2 フラグメントのサポートに必要なライブラリ

サポート・ライブラリと標準ライブラリの違い

サポート・ライブラリと標準ライブラリの違いは、上記のサンプル「FloatingActionButtonBasic」で見ることができます。

古いAndroidにはフラグメントをアクティビティ上に置くという考えがありませんでした。 そこで、古いAndroidでは「android.support.v4.app.Fragment」を「android.support.v4.app.FragmentActivity」 の上に置くという方法を取ります。

そこで、起動するアクティビティ(Android Studioでは「MainActivity」と命名される)は「Activity」ではなく 「FragmentActivity」を継承するようにします。

Android標準の「android.app.FragmentTransaction」に代えて「android.support.v4.app.FragmentTransaction」を用います。
また、「FragmentTransaction」を得るための「FragmentManager」も「android.support.v4.app.FragmentManager」です。
呼び出すメソッドは「FragmentActivity」が持っている「getSupportFragmentManager」です。


標準ライブラリ使用に戻すには - フラグメント

新しいAndroid「最新の仕様」を使った方法に戻すには、この「逆」を行います。

「フラグメント」を「android.support.v4.app.Fragment」から「android.app.Fragment」に戻すことを考えましょう。 上記のサンプル「FloatingActionButtonBasic」がちょうどその対象です。

最小ターゲットを変更

実は最初にしなければならないのは、アプリの「ターゲット」です。
最小(もっとも古い)ターゲットを「フラグメント」登場以前に設定してあると、コンパイルエラーが出ます。

サンプルが「サポート・ライブラリ」を用いているということは、古いAndroidにも対応させようという意図があるのですから、 最小ターゲットは古いはずです。

アプリのターゲットは、「Android Studio」では「Gradleスクリプト」に記述されるようになりました。

Gradleスクリプトを開く方法は上記と同様「build.gradle(Module:Application)」と書かれているノードですが、 エディタ上での編集箇所が違います。
図3に示す「minSDKVersion」のバージョン番号を新しいものにしておきます。図2では 最新の「21」になっています。
図3 「minSDKVersion」の数字。これは最新

フラグメントのAPIを変更

フラグメントのAPIのほとんどは、クラス名は新旧同じで、パッケージ名が違うだけです。
そこで、インポート宣言で「android.support.v4.app」という パッケージで宣言されているクラス名を「android.app」に変更すれば、APIの変更は完成です。


アクティビティのAPIを変更

アクティビティのAPIも変更しなければなりません。「ふつうに戻す」という感じになります。 継承するアクティビティを「FragmentActivity」から「Activity」に戻します。 インポートするクラスは「android.support.v4.app.FragmentActivity」は不要になり、「android.app.Activity」のインポートが必要になります (普段はインポートされているクラスですが、サポート・ライブラリを使うアプリではインポートされていないことがあります)


メソッドを変更

上で説明したとおり、メソッド「getSupportFragmentManager」を「getFragmentManager」に書き換えます。


フラグメントのサポート・ライブラリは、このように少ない変更で標準のライブラリと相互変更できます。
他のサポート・ライブラリではもっと複雑な場合があります。「アクション・バー」の例で確認しましょう。

標準ライブラリ使用に戻すには-アクション・バー

「アクション・バー」がサポート・ライブラリと標準ライブラリの間で変更しにくいのは「テーマ」の変更も必要だからです。

サンプル「ActionBarCompat-Basic」を開く

「アクション・バー」を表示するサンプル「ActionBarCompat-Basic」を開きます。名前に「Compat」がついているのは「Compatible(コンパチブル、互換性がある)」 かその種類の意味です。
サンプル・フォルダの「ui」のすぐ下に「ActionBarCompat-Basic」というフォルダがあります。開くと、「Android Studioのアイコン」がついているノード はないかも知れません。その場合、「build.gradle」のノードを選択して開きます。
図4 「ui/ActionBarCompat-Basic」
図5 「build.gradle」でも開ける

サポート・ライブラリ

「ActionBarCompat-Basic」ではやたらにたくさんのサポート・ライブラリを導入していますが、 「アクション・バー」に必要なのは「com.android.support:support-v4:21.+」と「com.android.support:appcampat-v7:18.0.+」の2つです。

図6 いろいろ導入されている

古いAndroidで動かしてみる

「ActionBarCompat」は古いAndroidでも動くように作ってあるサンプルですから、「GingerBread(Android2.3)」のエミュレーターで動かすことが できます。ただし、筆者が動かしてみたところ、サンプルの「テーマ」が白色系に設定されているため、 白色のアクション・バー・アイコンが見えないのではないかと思います。

応急措置として、「values/template-styles.xml」を開いてください。添え書きのないファイルです。
(「添え書き」については、「Androidプロジェクトの構造」で説明しています)

図7 「template-styles.xml」を開く

テーマの指定の最も基本的なところを変更します。「Theme.Light」と書いてあるところを「Theme」にします。昔のテーマは「Light」 を付加しなければ、黒基調のデザインになりました。

図8 テーマを黒基調にする
図9 「GingerBread」のエミュレーターでアクション・バーが使える
では、このサンプルを標準ライブラリの「アクション・バー」を使う形に戻してみましょう。

最小SDKを新しくする

図3で説明したように、「Gradle」スクリプトを編集して、「minSDKVersion」の値を新しいものにしておきます。

スタイルを普通のものにする

サンプル「ActionBarCompat-Basic」の「AndroidManifest.xml」を見てください。「android:theme」の値が「Theme.AppCompat」になっています。 これは、「サポート・ライブラリのアクション・バーを使うテーマ」を意味します。

図10「android:theme」の値

これを修正して、普通のテーマにします。それは「AppTheme」という名前です。これを書いておけば、動かすAndroid OSの標準テーマになります。 最近のAndroid OSの標準テーマでは標準の「アクション・バー」を使うことになっていますから、これでOKです。

図11「AppTheme」にする

メニューのXMLを修正

リソース・ファイル「menu/main.xml」を編集します。ここに書かれたメニュー・アイテムが、アクション・バー上ではアクション・ボタンになります。

アクションボタンの表示の優先順位を示す「showAsAction」の「名前空間」が「support」になっています。

図12「support」という名前空間

これを「android:showAsAction」に変更します。エディタに「赤の波線」が表示されるようですが気にしないでください。「名前空間は supportにしたほうがいいんじゃないですか」という警告のようです。そのままでもコンパイル・エラーにはなりません。

図13「android:showAsAction」にする

名前空間「support」はXMLの最初に、名前空間「android」とともに記述されています。「support」の名前空間は使わないので、消去します。

図14 名前空間「support」は不要

「MainActivity」を修正

「ActionBarCompat-Basic」のJavaプログラムは「MainActivity」だけです。いよいよ、これを編集します。

まず、サポート・ライブラリのクラスをインポートした宣言を削除します。
図15 サポートクラスのインポートを削除

ActionBarActivityの継承をやめる

MainActivityはサポート・クラスであるActionBarActivityを継承しています。これをやめて、普通の「Activity」を継承します。編集の 中で「android.app.Activity」をインポートすることになるでしょう。

図16 これを普通の「Activity」にする

基本的には、これで作業は終わりです。


メニューアイテムをコードで書く場合

しかし、サンプル「ActivityCompat-Basic」には、メニューアイテム(アクション・バー上ではアクション・ボタン)をXMLではなく Javaのコードで記述するサンプルがひとつあります。

メソッド「onCreateOptionsMenu」を見てください。リスト1の部分が、「Location」というメニューアイテムの作成と設定です。 インポートを削除したので、参照エラーになっているでしょう。

リスト1 メニュー・アイテムをコードで記述
MenuItem locationItem = menu.add(0, R.id.menu_location, 0, R.string.menu_location);
locationItem.setIcon(R.drawable.ic_action_location);
MenuItemCompat.setShowAsAction(locationItem, MenuItem.SHOW_AS_ACTION_ALWAYS);

リスト1では、「MenuItemCompat」を用いる部分だけを書き換えます。標準のメニュー・アイテムでは直接setShowAsActionのメソッド を使えるからです。

リスト2 メニュー・アイテムがshowAsActionを呼ぶ
locationItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
図17 標準のアクション・バーを用いる

この実験により、古いAndroidでもアクション・バーを使えるようにするには、逆の手順を踏めばよいことがわかります。


本書の目次へ
このサイトのトップへ