2019/09/23

Androidアプリ開発:非同期処理のAsyncTaskでのメモリリーク警告の原因と解消方法

Androidで、処理を非同期に実行したい場合は、AsyncTaskを使うのが基本。AsyncTaskは、スレッドプールからスレッドを割り当てて非同期に処理を実行し、UIスレッドで完了処理が実行されるようメッセージなどの処理を実装してくれている。具体的には、
AsyncTaskをベースとするクラスで、doInBackgroundとonPostExecuteメソッドに非同期処理本体、完了時の処理を実装し、インスタンス化してexecuteメソッドを実行すると非同期処理がキックされる。ネットワークを使う処理はUIスレッドでは実行できないので、AsyncTaskなどを使った非同期処理が必須。

ここでAsyncTaskの拡張クラスを定義する際によく使うテクニックが、無名クラス(Anonymous Class、匿名クラスとも呼ばれる)だ。あるクラスのメソッド内で拡張クラスを定義できる。この時、クラスに名前を付ける必要がないので、無名クラスと呼ばれる。非同期処理をキックする処理の近くに処理の内容をかけるし、無名クラスをインスタンス化するオブジェクトのメンバにアクセスできるというメリットもある。これは便利。

無名クラスを定義しているクラスのオブジェクトのメンバにアクセスできるのは、明示的には書かないが、無名クラスのオブジェクトが、その外のクラスのオブジェクトへの参照を隠し(implicit)持っているから。これは実は注意が必要で、コンパイル時にも警告が出る。"This AsyncTask class should be static or leaks might occur."というあれだ。私のようなJava初心者には結構難しい警告である。

非同期実行しているライブな無名クラスのオブジェクトが、そのオブジェクトを作った元オブジェクト参照していることになるので、元オブジェクトが破棄されてよいオブジェクトであっても破棄されないことになる。メモリリークが起きるかもしれない、というわけ。

そんなことあるのかい? と思われるかもしれないが、Activity から非同期処理をキックしたと考えてみると良い。非同期処理の進行とは無関係にActivityは閉じられ破棄される。非同期処理が長く走る処理だと、AsyncTaskのオブジェクトがActivityを参照しているため、Activityがいつまで経っても破棄されないことになる。非同期処理が短時間の処理ならあまり神経質になる必要はないのかもしれない。

この関係を解消するやり方は、非同期処理用のクラスを外に作ること。非同期処理で元オブジェクトを参照しないなら、これで解決できる。しかし、多くの場合は、元オブジェクトを参照したくなるはず。だって、非同期処理は、キックされたところにある処理に関係が深いだろうから。

どうしても元オブジェクトへの参照が必要な場合は、WeakReferenceという仕掛けを使うと良いようだ、これも新たにクラスを作らなければならないのだが、元オブジェクトへの参照をWeakReferenceでラップして保持するようにする。実際にそれを参照する処理を実行するときには、ライブな参照を取り出せたときだけ実行する形になる。

ということで、コンパイラの警告は消せるのだが、よくよく考えてほしい。特に、元オブジェクトがActivity,の場合。イベントドリブンに処理が分解できていて、Obseverパターンがうまく実装できている場合、元Activityへの参照は消せる場合も多いはず。非同期処理でデータのリポジトリが更新され、そのリポジトリを見ているObserverが登録されていて、Observerパターンでビューが更新されるような形がきれいに出来上がっているなら、非同期処理の完了処理でActivityが直接参照されることはない。

どっちを取るかは、、、メンテの必要性かかっているのかなぁ。


2019/09/18

Androidアプリ開発:データとビューの整理の考え方とObserverパターン

データを扱い始めると、データとビューをどうつなげるかを整理しないと、あっという間に混乱が襲ってくる。たとえActivityが一小さなアプリであっても、表示されるデータが変化する場合、想像以上にアプリの構造は複雑になっていく。ネットワーク経由でデータを取得する場合は、なおさらだ。

加えて、処理はイベントドリブンな形で実現しなければならない。何も考えずに書いていると、巨大なActivityができあがる。これば絶対おかしいと思い調べてみると、Fat activityというよくある罠。

Fat Activityは、アプリのクラス構造の設計を適切にすることで解決できる。昔からの定石があり、この先人の知恵は絶対に参考にすべきだ。MVC(Model-Vew-Controller), MVP(Model-View-Presenter), MVVM(Model-View-View Model)などのキーワードで検索すると、ありがたい情報がたくさん見つかるはずだ。

ポイントは、UIのイベント・画面更新、データの維持、これらのつなぐロジックをそれぞれ別のクラスとして実装し、かつ、これらのクラス間の依存関係を極力減らすような実装にすることだ。 依存関係を減らすカギが、Observerというデザインパターンである。

MVCやMVPなどの考え方をクラス設計に取り入れるだけで、Activityの混沌は大きく解消されると思う。Activityが一つのような小さなアプリでも、絶対にこれらの考え方を取り入れないと、メンテできないアプリになると思う。

複数のオブジェクトでアプリを構成するようになると、オブジェクトの状態変更をどう知らせるかが、次の悩みポイントになる。単純にクラス間でメソッドを呼び出す形で通知することもできるが、これをやると、状態変更を知りたいクラスが複数あると破綻する。そんなことあるのか?と思うかもしれないが、リストビュー、グラフビューなど、Viewが複数ある方が普通だ。同時にアクティブにはなっていないかもしれないが、表示の形態を切り替えられるのは普通だ。

ここで登場するのが、Observerと呼ばれるデザインパターンだ。あるオブジェクトが、誰かわからない外部のオブジェクトに状態の変化を伝えたい場合、変化が発生したときに呼び出すメソッドを含むインタフェースを定義する。変化を知りたいオブジェクト(Observer)は、このインタフェースを実装し、自身を変化の発生元のオブジェクトに登録する。このObserverのオブジェクトは、変化の発生元のクラスが使っているインタフェースさえ実装していればよく、どんなクラスでも構わない。これによって、状態変化元とそれを観測する側のクラスの依存関係をなくしている。インタフェースは特別なものでなくてよくて、Runnableインタフェイスなどで十分出会う。

ソース側は、Observerオブジェクトの登録・削除を受け付けるメソッドを用意し、状態変化時に登録されたオブジェクトが実装するインタフェースメソッドを呼び出せば良い。このとき、ソース側はObserverのクラスは知らなくて良い、というところが重大なポイント。これによって、ソース側はObserverとは独立して開発ができることになる。

一方のObserver側は、オブジェクトの登録、通知インタフェースに変更がない限り、ソース側の実装から切り離される。つまり、こちらも独立して開発、メンテができるようになる。

実装が隠蔽され、他のクラスとの依存関係がへり、テストもしやすくなり。効果は、小さなアプリでも絶大。たぶん、当たり前のことなんだけど、一度実際に罠にハマって悩んでここにたどり着くと、その効果がよくわかります。

2019/09/15

PaypayのためにYahoo! カードを作って設定したら、Yahoo!公金支払いの設定も変わる

近所のスーパーでPayPayが使えるようになったので、PayPayを使ってみることにした。

主に買い物するのは妻なので、私がチャージして、妻に残高を送る必要あり。チャージするには、セブンイレブンで現金でチャージ、Yahoo!ウォレットに登録されている銀行口座からチャージ、Yahoo!カードを登録してチャージが一般的。

セブンイレブンで現金チャージは、それってキャッシュレスなのか? という気がするので、却下。銀行口座は、メインの銀行口座が三菱UFJなのだが、ここだけYahoo!ウォレットに登録できないので、これも却下。

仕方がないので、Yahoo!カードを作った。申し込みはオンラインで完結して、一週間もしないうちにカードが届いた。で、申し込むと初回登録のような手続きがあって、それを完了すると使えるようになる。

この登録が曲者。これを実行すると、Yahoo!ウォレットの「通常使うお支払い方法」にYahoo!カードが登録されるのだ。

なにが曲者かというと、Yahoo!ウォレットで支払っている支払いのカードが変わる。Yahoo!ウォレットはYahoo!が提供するサービスの支払い全般に使われているので、それらの支払いカードが変わる、ということ。私の場合、Yahoo!公金支払いの支払いカードが変わっていて、水道料金の支払いが一回だけYahoo!カードに行ってしまった。

よく読むと、初回登録でYahoo!ウォレットの設定が変わると書いてあるのだが、たぶん、それを読んでも、Yahoo!公金支払いの支払いカードが変わることは気が付かなかったろうなぁ、と。なんで気が付いたかというと、ふと気づいたとしか言えないのだが。

ちなみに、PayPayへのクレジットカードの登録と、Yahoo!ウォレットのカードの登録は別にできる。いろんな支払いをしれっとYahoo!カードに持っていくのは、やめてほしい。

Androidアプリ開発:リソース、ダイアログ、Preferencesを扱うときのContext

Androidアプリを作っていると、ダイアログで利用者の応答を得たり、SharedPreferencesで設定を保持したり、したくなる。というか、する。また、表示するメッセージやUIコンポーネントに張り付ける文字列はリソースで定義する、ということをする。

これらのことをしようとすると、Contextというオブジェクトに触ることになる。Contextは、アプリケーションの構成要素が共通に必要な情報を保持するオブジェクト、ということなのだが、これがとても初心者には難しい。正直、いまだによくわからない。

アプリケーションのグローバルな情報ということなので、設定を保持するSharedPreferences、文字列を保持するリソースへのアクセスのインタフェイスを提供するのは分かるのだが、アプリケーションからアクセス可能なContextオブジェクトは複数ある、と言われると、訳がわからなくなる。

Contextオブジェクトはアプリケーションに一つではなくて、Activity, Application, ServiceといったクラスがContextクラスを拡張していて、これらのクラスのオブジェクトがContextオブジェクトそのものなのだ。まぁ、訳が分からない。グローバルな環境情報は、一つではないのか。

なぜこうなっているかというと、Activity, Application, Serviceのそれぞれで共通に必要な情報が微妙に違うから、ということらしい。例えば、UIのスタイルを決めるThemeの仕組みがある。Themeは、アプリケーションのManifestで定義される共通情報だが、ThemeはApplicationのレベル、Activityのレベルで定義できるため、それぞれのContextの実装で保持するようになっているようだ。

正直、わかったような、わからないような。

アプリを作り始めた人が最初にContextに触るのは、SharedPreferencesへのアクセスと、リソース化した文字列の取得ではないかと思う。通常、PreferenceManager#getDefaultSharedPreferencesで、SharedPreferencesオブジェクトを取得できる。ただ、このメソッドの引数としてContextオブジェクトを渡す必要がある。Activityクラスの中でSharedPreferencesオブジェクトを取得する場合は、thisを渡せばオブジェクトが取得できる。

アプリの作りが進むと、どうしてもActivityの実装がごちゃごちゃするので、データの扱いを別のクラスで管理しようということになる。そうすると、SharedPreferencesをラップするようなstaticなクラスをつくったほうが良いかな(あるいはsingletonパターンを使うか)、という感じに必ずなる。で、このクラスの中の処理でPreferenceManager#getDefaultSharedPreferencesを実行しようして、Contextはどこから持ってくるの? ということで悩むことになる。

じゃあ、初期化の際にこのクラスにActivityオブジェクトの参照を渡せばよいのかというと、ちょっと気持ちが悪い。ActivityのonCreateはUIコンポーネントの初期化に専念させたい。他のオブジェクトの初期化処理をここに入れるのは、なんだか気持ちがよくない。仮に、アプリケーションを起動するときの入り口が複数ある場合、この初期化をすべての入り口に書かなければならなくなる。そんなケースがあるのか? と思うかもしれないが、ある。私が作ったユーティリティが、実際、アプリ起動の入り口が2つある。

じゃあどういう手があるかというと、Applicationクラスを独自に拡張したクラスを作って、staticメソッドでそのインスタンスを取得できるようにしておく、という方法がよく使われるようだ(Manifestにこのクラスを登録しておく必要がある)。このクラスのオブジェクトは、アプリケーションが起動する際にシステムによって生成されて、アプリケーションが稼働している間、存在している。これのonCreateが、アプリケーション起動時に呼ばれるコールバックなので、Activityのライフサイクルに関係なく、ここにグローバルな初期化処理を記述できる。そして、Applicationクラスの拡張なので、getApplicationContextでコンテクストが取得できる。

これで、Contextが必要な時はすべてここから取得して解決、かというとそうでもなくて、ActivityやViewに係る処理でContextが必要な場合は、Activityをコンテクストを使わないといけない。ダイアログ作成で必要なContextも、Activityの方。

Application ContextからActivity Contextを取り出せるような形になっていれば、すっきりわかりやすいように思うのだが、、。そうもいかない理由があるのであろう。




2019/09/14

IIJmioひかりの速度

2018年秋にADSLからIIJmioひかりに切り替えた。

切り替え前に調べたときは、遅い時間帯がある、IPoEオプションをつけた方がよい、などとされていた。

で、切り替えると、本当に遅い、と思わせる時間帯は実際にあった。が、我が家の地域の設備増強が、切り替え後に二回実施され、大幅に改善したように思われる。

計測するサイトによるが、200Mbps以上とでることもあるし、5MbpsなどADSLよりも遅い、というような結果が出ることはなくなった。

今でも、IIJmioひかり+遅い、で検索すると、結構IPoEオプションをつけた方がよいよー、というページが出てくるが、いつの計測結果に基づいて書いているのか、よく注意してみた方がよい。Googleで検索すると、ページの更新日なのか作成日なのかが表示されるので、新しいページなのかと思ってみても、中に書かれている速度計測日は2017年ころだったりする。

私の地域の場合、1年間の間で2回の設備増強がされているようであり、ちゃんと設備投資しているように見える。サービスの性質上、個別の改善には応えられないけど、全般的には改善する意思のあるサービスのようには、私は思えます。

ま、どのサービスの評判・口コミにも当てはまりますが、元になっている速度計測の時期をよく確認するのが良いかと。

2019/09/12

Androidアプリ開発:イベントドリブンなプログラミング

Androidのアプリでは、いろいろな処理は、UI操作からのイベント処理、Activityのライフサイクルに関するコールバックなどのイベントから始まる。これらのイベントは、いわゆるUIスレッドに配信される。UIスレッドは各種イベントの受付と、UIの更新を受け持つ。Android全体の動作をスムーズにするためには、イベント処理すみやかに終了して、Android OSに制御を返さなければならない。UIスレッドでは、何かの処理の完了を待つことも許されない。

つまり、時間のかかる処理は別スレッドで実行しなければならない。ネットワークからデータを取得する処理も、Activityのイベント処理とは別のスレッドにしなければならない。
これは何を言っているかというと、「更新ボタンがタップされたから、データを新たに取得して画面を更新する」、「送信ボタンが押されたので、データを送信し、結果を取得して、画面を更新する」といった処理を、一連のフローで記述できない、ということだ。これらを、何某かのイベント契機で実行される処理に分解しなければならない。いわゆる、イベントドリブンな形に分解しなければならない。これは、とても大きなポイント。

「更新ボタンがタップされたから、データを新たに取得して画面を更新する」は、
・更新ボタンタップ → データ取得処理を開始する。
・データ取得完了 → 画面を更新する。
という2つのイベント処理に分解して実装しなければならない。それぞれ、コンポーネントのイベントリスナー、非同期処理の完了ハンドラに実装する形になる。

私が小さなAndroidアプリを書いた印象では、処理が複数のイベント処理に分割されるため、慣れるまでは見通しが悪く感じた。一方で、それぞれの処理がコンパクトになり、その処理自体は簡潔で単純になるので、かえってスッキリするようにも感じられる。多分、テストもしやすくなるんだろうなと思う。

注意するところは、イベント処理の実装の仕方がいろいろあり、迷子になりやすいことか。クラスのメソッドとして実装される場合は処理を探しやすいが、匿名クラスのオブジェクトのメソッドによる実装を多用すると、個人的には見通しが悪くなると感じる。

例えば、UIコンポーネントのイベント処理は、イベントリスナーをActivityのメソッドとして実装することもできるし、イベントリスナーのインタフェイスを実装するオブジェクトをUIコンポーネントにリスナーとして登録することでも実現できる。

一概に、どちらが良いとは言えない。個人的には、クラスのメソッドとしてイベント処理が実装されていたほうが、コードを探しやすくてよいように思う。匿名クラスの実装にもメリットはあり、匿名クラスであるべき場合もある。まぁ、多分、古い人間なんでしょう。

いずれにしても、イベント処理を普通のクラスのメソッドで実装するのか、匿名クラスのメソッドで実装するのか、一貫したスタイルを決めておくのが良いと思われる。

で、なるほどなー、そうかそうか、完全にイベントドリブンで考えないといけないんだ、といってその後何も考えずにイベント処理を作り込んでいくと、、、巨大で複雑なActivityができあがる。「あれ? なんかActivityのコードが膨らんでいるけど、こんなんでいいんだっけ?」と薄々心配しているのを放置して先に進み、機能追加してイベント処理が増えてくると、「これはなにか間違っている」、と感じるくらい、あっという間にコードが膨らむ。

次の罠、"Fat Activity”だ。

2019/09/11

Androidアプリ開発:アプリの起動にまつわるライフサイクルコールバック

Androidアプリを勉強も兼ねて作った。

お試しでAndroid Studioでコンポーネントを並べて、ビルドすると、コンポーネントが表示されるアプリが出来上がる。で、ここに何かデータを表示しようとすると、ライフサイクルにまつわるコールバックの処理と、データとビューをどう管理するか、という根源的な話かあっという間に迫ってくる。

まず、どうしても対処しないといけないのが、Activityのライフサイクルに関するコールバック。Android OSと深く連動したActivityのライフサイクルと、その状態遷移に伴うコールバックの処理がなかなか難しい。

普通のデスクトップアプリもイベント処理の要素は当然あり、UI処理を実行するするスレッドが決まっていて、そいつがいろいろなイベントを処理するということは、普通にある。

が、Activityが破棄された、回復させろ、というイベントは、メモリが少ないスマホならでは、の状態遷移である。

Activityの破棄・回復だけなら、回復に必要なデータを決めて、それの保存、回復すれば良いのでしょ? というのは正しいが、100点ではない。破棄・回復の間にいくつかのコールバックが呼び出されるので、どのコールバックで何を処理するのかをきちんと決めないといけない。

回復の処理で実行されるコールバックをみると、ランチャーからアプリを起動する時や、Activityがバックグラウンドからフォアグラウンドに復帰するときにも発生する。よって、Activityの起動処理は、Activityの破棄から回復の流れ、バックグラウンドからフォアグラウンドへの復帰の流れも踏まえた設計にした方が良い、ということ。ここをよく考えておかないと、後でブラッシュアップするときに、確実にライフサイクル処理を見直すことになる。

具体的には、Activityの起動・復帰・回復処理はonCreate, onRestart, onStart, onResumeの組み合わせで、Activiyの停止・終了処理はonPause, onStop, onDestoryの組み合わせで作ることになる。このように、Androidアプリでは、1つの処理に思える処理でも一連のコールバックやイベント処理に分割して実装しなければならないことが多くある。このイベントドリブンの考え方に慣れることがとても重要。面倒だと思っても、はじめからコールバックやイベントに合わせて処理を分割しておいた方が、手戻りが少なくなるはずだ。




2019/08/24

IIJmioでクーポン利用の切り替えをクイック設定パネルから実行する

IIJmioを使って、家族三人分を安く仕上げてます。

IIJmio は、通信速度を低速、高速で切り替えられて、低速モードで使っている場合、通信量を消費しない使い方ができる。普段は、メール、Lineくらいしか使わないので、低速で十分満足している。長時間でなければSpotifyも使えるし。

パパッと地図を見たり検索したりする場合は高速モードに切り替えるのだが、このためのアプリが提供されている。切り替えを実行するAPIも公開されていて、これを使ったアプリもいろいろ公開されている。

アプリを使っている最中にパッと切り替えられるのが良いのだが、探し方が悪いのか、なかなか良いのが見つけられず。ならば、と、Androidアプリ開発の経験も兼ねて、クイック設定パネルからクーポン利用を切り替えるアプリを作ってみた。

結構、快適。テストに協力いただける方は、野良アプリですが、お試しあれ

追記(2019/08/26)

頑張って作った後に、これだ! というアプリ「Mio Mix」を発見しました。こちらのほうが、よくできているように思います。シンプルな方がよい、という奇特な方は、私の野良アプリもお試しください。


2019/03/16

英検 準一級の参考書

英検 準一級を取得した。あまり理由はないのだが、、、、。ちょっとやってみようと思い立ち。

英語は、好きだし、得意な方だ。とはいっても、読めるだけで、しゃべり、作文は得意ではない。そもそも、日本語でもそんなに意見したりしゃべる方ではないところに本当の問題があるのだが。

やってみようと思いたったのが、12月ごろ。試験は、一次試験が1月、二次試験が3月。思い立ってみたものの、あまり時間がない。リーディングの過去問を解いてみるも、単語力がちょいと足りない感じ。どういう試験形式なのか調べると、ライティング、スピーキングもあるので、ちょいと頑張って勉強しないとあかんかなという感じ。ライティング、スピーキングは、時事ネタ、社会ネタを自分の意見として論理だてて書いたりしゃべらないといけないので、ネタを仕入れることも必要な感じ。

参考書が必要だ、ということで、使ったのが、3冊。

1冊目は、成美堂出版の英検準1級ポイント攻略問題集。ライティング、スピーキングまで一通りの練習にはなる参考書だが、リーディング、リスニングの問題の対策として購入した。解説がシンプルで、一通りの問題数があり、自分には向いていると思い購入。これを、3、4回集中的にこなす。リスニングの教材としては、通勤時間を使ってもっと聴いたかな。

2冊目は、旺文社の旺文社の英検準1級 文で覚える単熟語。単語、熟語勉強用に編集された参考書のようであるが、時事、社会ネタの分野ごとにある程度の長さの文章がたくさん収録されており、これで時事・社会ネタのポイントをつかむことができるように思う。これは、自分で選んだわけではなく妻が買っていたものだったのだが、かなりレベルが高いように思う。分量が多いので、深くは読み込んだり聴いたりはできなかったが、これも通勤時間を使って、2、3回は聴いただろうか。

この二冊で、単語、熟語は準1レベルに対応できるように思う。一次試験に必要な時事・社会ネタも仕入れられ、最低限のライティングのポイントや書き方のパターンもつかめるように思う。

この2冊を4,5回通読、通勤時には付属のCD-ROMを聴いて耳を慣らし。これで、一次試験に臨む。なんと、海外出張の帰国の翌日が試験だったが、合格!

ライティングがちょっとあかん感じだった。ライティングは、一切練習をせずに望んでしまったのだが、必ずやっておくべき。少なくとも時間配分を知るために、何度か文章を実際に書いてみるべきだ。頭で文章を作るのと、紙に書き起こすのとでは、かかる時間が全然ちがう。

長文系も、読み解き方のポイントを練習を通じて、もう少し頭に入れておいた方がよかったように思う。読めると思っていても、試験ではポイントを素早く抑えないといけないので、コツをつかむ必要があるように思う。

ライティングと長文系の問題で想像以上に時間がかかり、解答を見直す時間がなくなってしまい、おっとしまった、という感じの終わり方になってしまった。せっかくの参考書をもっと活用すべきだったが、参考書の勉強を通じて身についた単語が出てきて、参考書は役に立ったと感じている。

で、二次試験に臨むということで、面接用の参考書を探し、3冊目は、Jリサーチ出版の英検準1級面接大特訓。買った後で気が付いたのだが、ちょっと古い。が、これは、よかった。面接のナレーションで必要そうな例文がみっちり詰まっている。加えて、12の面接の練習問題。さらに、時事・社会ネタのQ&A集。特に、例文とQ&A集が良かった。

例文は、かなりのボリュームがあるのだが、すべて暗記する勢いでこなすと、ナレーションの練習で、その例文が活用できるようになっている。どういう言い回しを使いこなせるようになっているとよいかがわかるようになっている。ナレーションの練習を集めた参考書もあるが、自分はしゃべりがぜんぜんできないので、この参考書の例文集は非常にありがたかった。

Q&Aも文や広くカバーしており、自分だったらどういう回答をするかなぁと考えながら読み込める。実は、これが役に立った。

で、面接試験に臨む。順番に待つのだが、待っている間は、こんなに長くしゃべらされるのか、というくらいに感じる。

で、自分の番。で、挨拶して入り、座ると雑談的な質問をされるわけだが、、、。まぁ、聞かれたことは単純だったのだが、想定外の質問。というか、ここでどんなことを聞かれうるのかのパターンをまったく想定していなかったので、あ、そうか、何を聞かれるか、何も考えてなかった! と、若干あせる。まぁ、答えられないものではなかったので、事なきを得る。

で、カードを渡されナレーション。ナレーションは、、、、失敗した。時間切れになったのだ。

あれ、カラーなんですね。おう、カラーなんだ! と面食らっていると、準備してね、と言われる。で、ストーリーを考え始めるが、、、。まとまらない。ここは、今でも、何をどう準備すればよいのか、よくわからない。試験の時には、本当に焦っていて、何をポイントに喋ればよいか、まとまる前に準備時間が終了。

で、ナレーションスタート。頑張ってちゃんと説明しようとして、つまりながらたくさん喋ると、あっという間に2分を使ってしまう。絵の中の要素をあれこれしゃべっちゃうと、あっというまに2分消化。最後のコマをしゃべっているところで、時間切れになってしまった。また、たくさん喋りたくなるというか、しゃべれちゃうコマがあって、そこで時間を使ってしまった。

喋りが本当に苦手なので、どういう言い回しをすればよいか、つなぎをちゃんと入れよう、登場人物の感情を入れよう、時制に注意しよう、登場人物のしゃべりをうまく組み込もう、といったことを頭に入れることを重点的に練習していたのだが、ライティング同様、時間を計っての練習をサボっていた。この時間感覚をつかんでおくことはとても大切。実は、2分は短い。喋れない人にとっては、とてつもなく短い。ナレーション前の準備時間の1分も、ちゃんと図って練習して感覚をつかんでおくべきだ。これ、絶対。

そのあとの質問は問題なく応対できたのだが、なんと、Q2からQ4が、この3冊目の参考書に掲載されていたのと同様の質問だったのだ。他の参考書でも出ているのかもしれないが、自分だったらどう答えるかなぁ、とまさに考えを整理していたので、さらさら、と答えることができた。

で、面接時間はどうだったかというと、自分の番はあっというまに終了。

で、面接もめでたく突破。ナレーションは全然ダメかなーと思っていたが12点もらえていた。まぁ、頑張ってしゃべり続ければ、何とかなる模様ではある。

全体には、ちゃんと勉強しなかったら、突破できない感じではありました。参考書は、どんなものでも、ちゃんとやっておくべき!