2015年9月21日月曜日

Androidアプリ開発 volleyをSingletonパターンで使う

  • 公開日:2015年09月21日

記事概要


aAndroidアプリ開発で、volleyをSingletonパターンで実装する記事です。

環境


  • Android Studio1.3.0
  • OS X Yosemite
  • com.mcxiaoke.volley:library:1.0.19
  • android sdk Version 23

はじめに


Android開発で、ネットワーク処理にvolleyを利用するかは賛否が別れるところです。
volleyは強力で便利なライブラリですが、使いこなせるようになるまでは、それなりの経験を積む必要があります。
また、典型的なパターン以外の処理をおこなおうとすると、それなりに手を加えないといけません。最悪、秘伝のタレのようなソースコードになってしまって、volleyライブラリ自体のupdateが不可能になってしまうケースもあるでしょう。
なのでvolleyは、万人に薦められるライブラリとは言えません。
とはいえ、使いどころを間違えなければ、これほど便利なライブラリもありません。googleの公式ライブラリという点も大きいです。
なので今回は、volleyをsingletonパターンで利用する方法を説明します。

volley implements singleton


もし、あなたのアプリケーションが、コンスタントにネットワーク接続を利用するなら、RequestQueueをSingletonパターンで実装すると効率的です。

volleyを実装する時に理解しないといけない重要な概念は、RequestQueueはActivityのcontextでなく、Application のcontextでインスタンスを作成しないといけないことです。
これは、RequestQueueが、アクティビティが再生成されるたびに再生成されるのではなく、アプリケーションのライフタイムがずっと続くことを保証します。

つまり、Activityが消失しても、network接続を保証するような実装を心がけるべきということです。

singleton class creates


では、singletonパターンでvolleyの実装を行ないます。
私がアプリを作成する場合、このクラスをutilパッケージで管理しています。


public class AppNetworkSingleton {

    private static AppNetworkSingleton mInstance;
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private static Context mCtx;

    private AppNetworkSingleton(Context context) {
        mCtx = context;
        mRequestQueue = getRequestQueue();

        ImageLoader.ImageCache imageCache = new LruCacheVolly();

        mImageLoader = new ImageLoader(mRequestQueue,imageCache);
    }

    public static synchronized AppNetworkSingleton getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new AppNetworkSingleton(context);
        }
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    }

    public ImageLoader getImageLoader() {
        return mImageLoader;
    }
}

ImageLoaderで利用しているLruCacheVollyは自作のメモリ管理クラスです。
大きなリスト表示などで大量の画像を表示するとき実装すると効果的です。
参考までに以下にコードを記載しておきます。


/**
 * VollyのImageCacheを利用したLruCacheクラス
 * キャッシュサイズを最大メモリの1/8と定義して初期化。
 * 機種に依存することなく容量をスケールできます。
 * 参考サイト : http://techbooster.org/android/hacks/16474/
 */
public class LruCacheVolly implements ImageLoader.ImageCache {

    private LruCache<String, Bitmap> mMemoryCache;

    public LruCacheVolly(){
        int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        int cacheSize = maxMemory / 8;       // 最大メモリに依存
        // int cacheSize = 5 * 1024 * 1024;  // 5MB

        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                // 使用キャッシュサイズ(KB単位)
                return bitmap.getByteCount() / 1024;
            }
        };
    }

    // ImageCacheのインターフェイス実装
    @Override
    public Bitmap getBitmap(String url) {
        return mMemoryCache.get(url);
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        mMemoryCache.put(url,bitmap);
    }
}

以上でvolleyを使う準備は完了です。
では、実際に実装してみましょう。

今回は実装に、自作アプリの「マウンテンチャンネル」を使います。
AppNetworkSingletonクラスのSingletonからgetImageLoaderメソッドを利用して、ImageViewにユーザー画像を設定します。


        // ImageViewを継承したBezelImageViewを生成
        BezelImageView userImage = (BezelImageView)drawerLayout.findViewById(R.id.user_image);
        // SingletoでgetImageLoaderメソッドを呼び出す
        ImageLoader mImageLoader =  AppNetworkSingleton.getInstance(getApplicationContext()).getImageLoader();
        // リスナーの生成
        ImageLoader.ImageListener userImageListener = ImageLoader.getImageListener(userImage, R.drawable.image_loading, R.drawable.nouserimage512512);
        // 設定
        userImage.setTag(mImageLoader.get(user.user_image, userImageListener));

では、ビルドして画面を確認してみましょう。

うまく表示されていますね。

まとめ


REST形式のAPIを利用する場合は、ネットワーク処理にvolleyを使うのを考えるのは良い選択だと思います。
volleyは概念さえ理解すれば便利なライブラリだし、動きも軽量で、なによりgoogle製なので今後もアップデートされ続けて、どんどんとよくなっていくことが期待できます。
とはいえ、初心者が扱うには敷居が高いのも事実です。仕様的に機能に追加実装をしないといけないアプリもあると思います。
なので、プロジェクト導入の際には、扱っているアプリが今後どういったスキルを持つメンバーをジョインさせるのかということまで考えて導入の可否を決めると良いのではないでしょうか。
個人的には、少人数で扱うアプリや、アップデートを高速で回すアプリなら、導入した方が便利だと思います。

以上

Androidアプリ【マウンテンチャンネル】


Android app on Google Play

JavaでSingletonパターンを学ぶのに適した本


Androidアプリ開発用にもっておきたい端末


関連記事 参考サイト

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

0 件のコメント:

コメントを投稿

Related Posts Plugin for WordPress, Blogger...