本「Android。 専門家向けのプログラミング。 第3版

画像 第3版では、統合されたAndroid Studio環境を紹介します。これにより、アプリケーション開発が大幅に促進されます。 プログラミングの基本を学ぶだけでなく、Androidの最も一般的なバージョンの機能についても学びます。 制約付きレイアウトやデータバインディングなどの新しいツール 単体テスト; アクセシビリティの手段。 MVVMのアーキテクチャスタイル。 ローカリゼーション 新しいランタイム許可システム。 すべてのトレーニングアプリケーションは、Android向けのプログラミングの重要な概念とテクニックを示し、実際のアプリケーションを体験できるように設計されています。



猫の下で本についてより詳細に、本「Multiple Downloads」からの抜粋



本の構造



この本では、8つのAndroidアプリケーションを作成します。 2つのアプリケーションは非常にシンプルで、1つの章で作成できます。 他のアプリケーションはより複雑になることが多く、最長のアプリケーションには13章が必要です。 すべてのアプリケーションは、重要な概念とテクニックを示し、実際のアプリケーションでの経験を提供するように設計されています。



•GeoQuiz-最初のアプリケーションでは、Androidプロジェクト、アクティビティ、レイアウト、および明示的な意図を作成する基本原則を探ります。

•CriminalIntent-職場での同僚の不正行為に関する情報を保存するために設計された、本の中で最大のアプリケーション。 フラグメント、「メインの詳細なプレゼンテーション」インターフェイス、リストインターフェイス、メニュー、カメラ、暗黙的なインテントなどの使用方法を学習します。

•BeatBox-敵を恐怖に陥れ、フラグメント、マルチメディアコンテンツの再生、MVVMアーキテクチャ、データバインディング、テスト、テーマ、およびグラフィックオブジェクトについて学習します。

•NerdLauncher-非標準のランチャー。意図とタスクのシステムの複雑さを明らかにします。

•PhotoGallery-パブリックデータベースから写真をダウンロードして表示するためのFlickrクライアント

Flickr アプリケーションは、サービス、マルチスレッドプログラミング、Webサービスへのアクセスなどの作業を示します。

DragAndDraw-このシンプルなグラフィカルアプリケーションでは、タッチイベントの処理とカスタムビューの作成を検討します。

•日没-この「おもちゃ」アプリケーションでは、水に沈む夕日の美しい景色を作成し、同時にアニメーションの繊細さをマスターします。

•Locatr-アプリケーションを使用すると、Flickrサービスにアクセスして現在の場所の周囲の画像を取得し、地図に表示できます。 マップサービスとマップの使用方法を学習します。



複数のダウンロード



現在、PhotoGalleryのネットワーク部分は次のように機能します。PhotoGalleryFragmentは、バックグラウンドスレッドでFlickrからJSONを受信するAsyncTaskインスタンスを開始し、JSONをGalleryItemオブジェクトの配列に解析します。 各GalleryItemオブジェクトには、写真のサムネイルバージョンがあるURLが保存されるようになりました。



次のステップは、これらのサムネイルをダウンロードすることです。 追加のネットワークコードは、FetchItemsTaskクラスのdoInBackground()メソッドに単純に追加できるように思われます。 GalleryItemオブジェクト配列には、100個のダウンロードURLが含まれています。 画像は100枚になるまで1つずつアップロードされます。 onPostExecute(...)を実行すると、RecyclerViewにすべて一緒に表示されます。



ただし、すべてのサムネイルを一度に読み込むと、2つの問題が発生します。 まず、多くの時間がかかり、ユーザーインターフェイスは完了するまで更新されません。 接続速度が遅い場合、ユーザーはビルウォールをよく見る必要があります。



画像






次に、画像の完全なセットを保存するにはリソースが必要です。 100個のミニチュアがメモリに簡単に収まります。 しかし、それらが1000個ある場合はどうでしょうか。 無限スクロールを実装したい場合はどうしますか? 時間の経過とともに、空きメモリが枯渇します。



これらの問題を考えると、実際のアプリケーションは、画面に表示する必要がある場合にのみ画像をダウンロードすることがよくあります。 必要に応じてダウンロードすると、RecyclerViewとそのアダプターに追加の要件が課されます。 アダプターは、onBindViewHolder(...)実装の一部としてイメージのロードを開始します。



AsyncTaskはバックグラウンドスレッドを取得する最も簡単な方法ですが、繰り返し実行される長時間の操作では、このメカニズムは最初はほとんど役に立ちません。 (これがなぜそうなのかについては、この章の最後にある「好奇心の強い人のために」のセクションで説明されています。)

AsyncTaskを使用する代わりに、カスタムバックグラウンドスレッドを作成します。 これは、必要に応じてロードを実装する最も一般的な方法です。



メインスレッドの相互作用



特殊なストリームは写真をアップロードしますが、メインストリームに直接アクセスできない場合、RecyclerViewアダプターとどのように対話して表示しますか?



靴屋と2つのFlashセラーを思い出してください。 背景Flashはサプライヤとの電話での会話を完了しました。次に、靴が注文されたことをチーフフラッシュに通知する必要があります。 メインフラッシュがビジーの場合、バックグラウンドフラッシュはすぐにこれを実行できません。 彼はカウンターで待機し、空き時間にメインフラッシュを傍受する必要があります。 このようなスキームは機能しますが、効率的ではありません。



各Flashにメールボックスを与えることをお勧めします。 バックグラウンドフラッシュは、靴が注文されたことを示すメッセージを書き込み、メインフラッシュドロワーに入れます。 メインフラッシュは、バックグラウンドフラッシュに何らかの製品がなくなったことを通知する場合にも同じことを行います。



メールボックスのアイデアは非常に便利です。 おそらく、売り手にはすぐに完了するべきタスクがありますが、現時点では完了していません。 この場合、彼はメッセージを受信トレイに入れ、空き時間に処理します。



Androidでは、ストリームで使用されるこのような「メールボックス」はメッセージキューと呼ばれます。 メッセージキューを使用するスレッドは、メッセージループと呼ばれます。 彼は、キューに表示される可能性のある新しいメッセージを何度もチェックします(図26.3)。



画像






メッセージループは、ストリームと、ストリームのメッセージキューを制御するLooperオブジェクトで構成されます。



メインスレッドはメッセージループであり、メッセージキューからメッセージを抽出し、メッセージに記述されているタスクを実行する制御オブジェクトを持っています。



メッセージループも使用するバックグラウンドスレッドを作成します。 これは、既製のLooperオブジェクトを提供するHandlerThreadクラスを使用します。



バックグラウンドストリームを作成する



HandlerThreadを拡張するThumbnailDownloaderという新しいクラスを作成します。 queueThumbnail()と呼ばれるコンストラクターとその実装スタブを定義します(リスト26.4)。



リスト26.4 ストリームコードのオリジナルバージョン(ThumbnailDownloader.java)

public class ThumbnailDownloader<T> extends HandlerThread { private static final String TAG = "ThumbnailDownloader"; private boolean mHasQuit = false; public ThumbnailDownloader() { super(TAG); } @Override public boolean quit() { mHasQuit = true; return super.quit(); } public void queueThumbnail(T target, String url) { Log.i(TAG, "Got a URL: " + url); } }
      
      





クラスは、1つの汎用引数<T>を受け取ります。 ThumbnailDownloaderユーザーは、各ダウンロードを識別し、ダウンロードの完了後に更新する必要があるユーザーインターフェイス要素を識別するオブジェクトを必要とします。 ユーザーを特定の種類のオブジェクトに制限する代わりに、一般化されたパラメーターを使用して、実装をより柔軟にします。



queueThumbnail()メソッドは、ロード識別子として機能するタイプTのオブジェクトと、ロードするURLを含むStringを受け取ることを想定しています。 このメソッドは、onBindViewHolderの実装でPhotoAdapterによって呼び出されます(...)。



PhotoGalleryFragment.javaファイルを開きます。 PhotoGalleryFragmentでThumbnailDownloaderタイプのフィールドを定義します。 onCreate(...)メソッドで、ストリームを作成して開始します。 onDestroy()メソッドをオーバーライドして、ストリームを終了します。



リスト26.5。 ThumbnailDownloaderクラスの作成(PhotoGalleryFragment.java)

 public class PhotoGalleryFragment extends Fragment { private static final String TAG = "PhotoGalleryFragment"; private RecyclerView mPhotoRecyclerView; private List<GalleryItem> mItems = new ArrayList<>(); private ThumbnailDownloader<PhotoHolder> mThumbnailDownloader; ... @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); new FetchItemsTask().execute(); mThumbnailDownloader = new ThumbnailDownloader<>(); mThumbnailDownloader.start(); mThumbnailDownloader.getLooper(); Log.i(TAG, "Background thread started"); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ... } @Override public void onDestroy() { super.onDestroy(); mThumbnailDownloader.quit(); Log.i(TAG, "Background thread destroyed"); } ... }
      
      





ジェネリックThumbnailDownloader引数で任意のタイプを指定できます。 ただし、この引数は、ロードの識別子として使用されるオブジェクトのタイプを指定することに注意してください。 この場合、PhotoHolderオブジェクトを識別子として使用すると便利です。これは、ダウンロードされた画像が最終的に到着する場所を同時に決定するためです。



いくつかのメモ:最初に、ThumbnailDownloaderのstart()呼び出しの後にgetLooper()呼び出しが続くことに注意してください(Looperオブジェクトについては、後ほど詳しく説明します)。 これにより、理論的に可能な(まれではありますが)競合状況を排除するために、フローの内部状態を継続できる状態になります。 getLooper()を呼び出す前に、onLooperPrepared()メソッドが呼び出されたことを保証するものはありません。そのため、Handler参照がnullであるため、queueThumbnail(...)の呼び出しが失敗する可能性があります。



次に、quit()を呼び出すと、onDestroy()内のストリームが終了します。 これは非常に重要なポイントです。 HandlerThreadスレッドが終了しない限り、ゾンビのように死ぬことはありません。 またはロックンロール。

最後に、PhotoAdapter.onBindViewHolder(...)メソッドで、ストリームのqueueThumbnail()メソッドを呼び出して、最終的に画像をホストするPhotoHolderオブジェクトと、ロードするGalleryItemオブジェクトへのURLを渡します。



リスト26.6。 ThumbnailDownloader接続(PhotoGalleryFragment.java)

 public class PhotoGalleryFragment extends Fragment { ... private class PhotoAdapter extends RecyclerView.Adapter<PhotoHolder> { ... @Override public void onBindViewHolder(PhotoHolder photoHolder, int position) { GalleryItem galleryItem = mGalleryItems.get(position); Drawable placeholder = getResources().getDrawable (R.drawable.bill_up_close); photoHolder.bindDrawable(placeholder); mThumbnailDownloader.queueThumbnail(photoHolder, galleryItem.getUrl()); } ... } ... }
      
      





PhotoGalleryアプリを起動し、LogCatデータを確認します。 RecyclerViewをスクロールすると、LogCatに行が表示され、ThumbnailDownloaderがすべてのダウンロード要求を受信して​​いることを示します。



HandlerThreadの実装が機能したので、次のステップはqueueThumbnail()に渡された情報を使用してメッセージを作成し、ThumbnailDownloaderメッセージキューに配置することです。



»本の詳細については、出版社のウェブサイトをご覧ください

» コンテンツ

» 抜粋



Android用クーポンの20%割引-Android



All Articles