2016-04-18 8 views
0

私はvolleyライブラリを使用しているプロジェクトを持っています。 私はMyApplicationクラスを持っている:Androidライブラリでvolleyを使用する方法

public class MyApplication extends Application { 
    public static final String TAG = MyApplication.class 
      .getSimpleName(); 

    private RequestQueue mRequestQueue; 

    private static MyApplication mInstance; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     mInstance = this; 
    } 

    public static synchronized MyApplication getInstance() { 
     return mInstance; 
    } 

    public RequestQueue getRequestQueue() { 
     if (mRequestQueue == null) { 
      mRequestQueue = Volley.newRequestQueue(getApplicationContext()); 
     } 

     return mRequestQueue; 
    } 

    public <T> void addToRequestQueue(Request<T> req, String tag) { 
     req.setTag(TextUtils.isEmpty(tag) ? TAG : tag); 
     getRequestQueue().add(req); 
    } 

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

    public void cancelPendingRequests(Object tag) { 
     if (mRequestQueue != null) { 
      mRequestQueue.cancelAll(tag); 
     } 
    } 
} 

今私のプロジェクトでは、私のManifestファイル内のクラス名を追加していことを使用します。

<application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" 
     android:name=".MyApplication" 
     > 

すべて正常です。

主な質問になると、私はボレーを使用する必要がある図書館も作っています。 私のライブラリでは、MyApplicationクラスを作成し、マニフェストにアプリケーション名を追加しました。私はまた、マニフェストにインターネット許可を追加しました。

私の関数を呼び出すとき、それは私にnull参照エラーを与えています。

Attempt to invoke virtual method 'com.android.volley.Request com.android.volley.RequestQueue.add(com.android.volley.Request)' on a null object reference 

私の質問:

A)私たちは、図書館でボレーのを使用することができます。右?

b)「はい」の場合、エラーが表示されるのはなぜですか?いいえの場合は、サーバーとどのように対話しますか?

私はmavenリポジトリを作成する予定ですので、メインプロジェクトファイルの変更はできません。

プロジェクトのマニフェストでアプリケーション名をlibrarieのMyApplicationクラスに変更しようとしました。その場合、サーバーに接続することができました。

しかし、ユーザーが自分のカスタムクラスのアプリケーション名を既に変更している場合は、どうすれば目標を達成できますか?

シングルトンクラスも試しましたが、同じエラーが表示されています。

おかげ

+0

ライブラリは 'Application'クラスを使用するはずですか?あなたはVolleyを使うのにそれを必要とせず、私はあなたが図書館でVolleyを使うことができると確信しています。 –

+0

addメソッドの前にgetRequestQueueを呼び出していますか? beacuseはRequestQueueのインスタンスを作成する場所です。 – Pablo

+0

@ cricket_007なので、プロジェクトには1つのアプリケーションクラスしかないと言ってもいいですか?ライブラリには独自のアプリケーションクラスはありませんか? – driftking9987

答えて

0

あなたがアプリケーションを拡張するシングルトンを作る停止する必要があります。その悪い習慣。ような何か:

public class MySingleton{ 
     private static MySingleton mInstance; 
     private RequestQueue mRequestQueue; 
     private ImageLoader mImageLoader; 
     private static Context mCtx; 

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

     private MySingleton(Context context) { 
      mCtx = context; 
      mRequestQueue = getRequestQueue(); 
      mImageLoader = new ImageLoader(mRequestQueue, new ImageLoader.ImageCache() { 

       private final LruCache<String, Bitmap> 
         cache = new LruCache<String, Bitmap>(20); 

       @Override 
       public Bitmap getBitmap(String url) { 
        return cache.get(url); 
       } 

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

     public RequestQueue getRequestQueue() { 
      if (mRequestQueue == null) { 
       mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext()); 
      } 
      return mRequestQueue; 
     } 

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

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

     public ImageLoader getImageLoader() { 
      return mImageLoader; 
     } 

     public void cancelPendingRequests(Object tag){ 
      if(mRequestQueue != null){ 
       mRequestQueue.cancelAll(tag); 
      } 
     } 

     public static boolean canConnect(Context context){ 
      ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
      NetworkInfo info = manager.getActiveNetworkInfo(); 
      if(info != null && info.isConnected()) return true; 
      return false; 
     } 
    } 

そしてMySingleton.getInstance(context)ようにそれを呼び出すことを.... 例えばMySingleton.getInstance(this).addToRequestQueue(request); このようにマニフェストに何も宣言する必要はありません。

+0

シングルトンクラスも作りました。しかし、この場合もnullpointer例外が発生しています。 – driftking9987

+0

あなたのコードを試してみると、私はそれを走らせました。それは私に同じエラーが発生した '原因:java.lang.NullPointerException:nullオブジェクト参照で仮想メソッド 'android.content.Context android.content.Context.getApplicationContext()'を呼び出そうとしました android.content.ContextWrapper.getApplicationContext (ContextWrapper.java:107) at com.iamanubhaw.xyz.MySingleton.getRequestQueue(MySingleton.java:50) '。 この行は次のとおりです。 'mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());' – driftking9987

+0

コンテキストを取得する場所は、実際にコンテキストが存在する前に作成されています。ブロードキャストレシーバーやサービスでこれを使用していますか、サンプルのユースケースや正確なユースケースを投稿してください。私はそのコードをfaliureなしで膨大な数のアプリケーションに使用しています。 –

0

RequestQueueはアプリケーションシングルトンでなければならないので、ライブラリ内でロックする必要はありません。むしろ、将来のアプリケーションがあなたのライブラリの使用を開始するために提供しなければならないインタフェースを定義してください。種類

interface RequestQueueProvider { 
    RequestQueue getRequestQueue(); 
} 

このアプリケーションでは、ライブラリの初期化コード、いくつかのクラスコンストラクタなどにいくつかのインプリメンテーションを渡す必要があります。アプライアンスはこれを使って自分のリクエストにすることができます。RequestQueue

+0

いくつかの例を教えてもらえますか? – driftking9987

+0

あなたの 'MyApplication'クラスは上記のインターフェースを実装していますが、Richard McFriendの' MySingleton'もそうです。あなたのライブラリには、例えば 'GreateQuestion'クラスがあります。このクラスは、' RequestQueueProvider'型のパラメータをコンストラクタリクエスタにリクエスタするため、 'GreateQuestion mGQ = new GreateQuestion(this);あなたのクラスで。または、GreateQuestion mGQ = new GreateQuestion(MySingleton.getInstace(this)); 'Richard McFriendの例を使用しているアクティビティの' onCreate'内。 – Serg

関連する問題