2016-03-09 1 views
0

Bonjour à tous, je suis en train de faire la liste personnalisée de vue avec une alimentation de volley suivant ce tutoriel: http://www.androidhive.info/2014/06/android-facebook-like-custom-listview-feed-using-volley/volley Image chargeur Erreur Excpetion

mais je suis une erreur avec le chargeur d'image je ne peux pas obtenir le blocage de celui-ci , j'espère que si quelqu'un peut me dire quel est le problème et comment dois-je résoudre en premier lieu :)

merci à l'avance

c'est l'erreur:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.asro9.customfeed/com.example.asro9.customfeed.MainActivity}: java.lang.NullPointerException 
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184) 
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233) 
     at android.app.ActivityThread.access$800(ActivityThread.java:135) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
     at android.os.Handler.dispatchMessage(Handler.java:102) 
     at android.os.Looper.loop(Looper.java:136) 
     at android.app.ActivityThread.main(ActivityThread.java:5001) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:515) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
     at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.NullPointerException 
     at Adapter.FeedListAdapter.<init>(FeedListAdapter.java:33) 
     at com.example.asro9.customfeed.MainActivity.onCreate(MainActivity.java:50) 
     at android.app.Activity.performCreate(Activity.java:5231) 
     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148) 
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233) 
            at android.app.ActivityThread.access$800(ActivityThread.java:135) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
            at android.os.Handler.dispatchMessage(Handler.java:102) 
            at android.os.Looper.loop(Looper.java:136) 
            at android.app.ActivityThread.main(ActivityThread.java:5001) 
            at java.lang.reflect.Method.invokeNative(Native Method) 
            at java.lang.reflect.Method.invoke(Method.java:515) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
            at dalvik.system.NativeStart.main(Native Method) 

je vais montrer les classes que j'ai créées!

FeedListAdapter.java

package Adapter; 


import java.util.List; 

import android.app.Activity; 
import android.content.Context; 
import android.text.Html; 
import android.text.TextUtils; 
import android.text.format.DateUtils; 
import android.text.method.LinkMovementMethod; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.TextView; 

import com.android.volley.toolbox.ImageLoader; 
import com.android.volley.toolbox.NetworkImageView; 
import com.example.asro9.customfeed.FeedImageView; 
import com.example.asro9.customfeed.R; 

import CustomFeed.AppController; 
import Data.FeedItem; 

/** 
* Created by asro9 on 3/7/2016. 
*/ 
public class FeedListAdapter extends BaseAdapter { 
    private Activity activity; 
    private LayoutInflater inflater; 
    private List<FeedItem> feedItems; 
    ImageLoader imageLoader = AppController.getInstance().getImageLoader(); 

    public FeedListAdapter(Activity activity, List<FeedItem> feedItems) { 
     this.activity = activity; 
     this.feedItems = feedItems; 
    } 

    @Override 
    public int getCount() { 
     return feedItems.size(); 
    } 

    @Override 
    public Object getItem(int location) { 
     return feedItems.get(location); 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     if (inflater == null) 
      inflater = (LayoutInflater) activity 
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     if (convertView == null) 
      convertView = inflater.inflate(R.layout.feed_item, null); 

     if (imageLoader == null) 
      imageLoader = AppController.getInstance().getImageLoader(); 

     TextView name = (TextView) convertView.findViewById(R.id.name); 
     TextView timestamp = (TextView) convertView 
       .findViewById(R.id.timestamp); 
     TextView statusMsg = (TextView) convertView 
       .findViewById(R.id.txtStatusMsg); 
     TextView url = (TextView) convertView.findViewById(R.id.txtUrl); 
     NetworkImageView profilePic = (NetworkImageView) convertView 
       .findViewById(R.id.profilePic); 
     FeedImageView feedImageView = (FeedImageView) convertView 
       .findViewById(R.id.feedImage1); 

     FeedItem item = feedItems.get(position); 

     name.setText(item.getName()); 

     // Converting timestamp into x ago format 
     CharSequence timeAgo = DateUtils.getRelativeTimeSpanString(
       Long.parseLong(item.getTimeStamp()), 
       System.currentTimeMillis(), DateUtils.SECOND_IN_MILLIS); 
     timestamp.setText(timeAgo); 

     // Chcek for empty status message 
     if (!TextUtils.isEmpty(item.getStatus())) { 
      statusMsg.setText(item.getStatus()); 
      statusMsg.setVisibility(View.VISIBLE); 
     } else { 
      // status is empty, remove from view 
      statusMsg.setVisibility(View.GONE); 
     } 

     // Checking for null feed url 
     if (item.getUrl() != null) { 
      url.setText(Html.fromHtml("<a href=\"" + item.getUrl() + "\">" 
        + item.getUrl() + "</a> ")); 

      // Making url clickable 
      url.setMovementMethod(LinkMovementMethod.getInstance()); 
      url.setVisibility(View.VISIBLE); 
     } else { 
      // url is null, remove from the view 
      url.setVisibility(View.GONE); 
     } 

     // user profile pic 
     profilePic.setImageUrl(item.getProfilePic(), imageLoader); 

     // Feed image 
     if (item.getImge() != null) { 
      feedImageView.setImageUrl(item.getImge(), imageLoader); 
      feedImageView.setVisibility(View.VISIBLE); 
      feedImageView 
        .setResponseObserver(new FeedImageView.ResponseObserver() { 
         @Override 
         public void onError() { 
         } 

         @Override 
         public void onSuccess() { 
         } 
        }); 
     } else { 
      feedImageView.setVisibility(View.GONE); 
     } 

     return convertView; 
    } 

} 

FeedImageVie.java

package com.example.asro9.customfeed; 
import android.content.Context; 
import android.text.TextUtils; 
import android.util.AttributeSet; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.LinearLayout.LayoutParams; 

import com.android.volley.VolleyError; 
import com.android.volley.toolbox.ImageLoader; 
import com.android.volley.toolbox.ImageLoader.ImageContainer; 
import com.android.volley.toolbox.ImageLoader.ImageListener; 
/** 
* Created by asro9 on 3/7/2016. 
*/ 
public class FeedImageView extends ImageView { 

    public interface ResponseObserver { 
     public void onError(); 

     public void onSuccess(); 
    } 

    private ResponseObserver mObserver; 

    public void setResponseObserver(ResponseObserver observer) { 
     mObserver = observer; 
    } 

    /** 
    * The URL of the network image to load 
    */ 
    private String mUrl; 

    /** 
    * Resource ID of the image to be used as a placeholder until the network 
    * image is loaded. 
    */ 
    private int mDefaultImageId; 

    /** 
    * Resource ID of the image to be used if the network response fails. 
    */ 
    private int mErrorImageId; 

    /** 
    * Local copy of the ImageLoader. 
    */ 
    private ImageLoader mImageLoader; 

    /** 
    * Current ImageContainer. (either in-flight or finished) 
    */ 
    private ImageContainer mImageContainer; 

    public FeedImageView(Context context) { 
     this(context, null); 
    } 

    public FeedImageView(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public FeedImageView(Context context, AttributeSet attrs, 
         int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    /** 
    * Sets URL of the image that should be loaded into this view. Note that 
    * calling this will immediately either set the cached image (if available) 
    * or the default image specified by 
    * {@link VolleyImageView#setDefaultImageResId(int)} on the view. 
    * 
    * NOTE: If applicable, {@link VolleyImageView#setDefaultImageResId(int)} 
    * and {@link VolleyImageView#setErrorImageResId(int)} should be called 
    * prior to calling this function. 
    * 
    * @param url 
    *   The URL that should be loaded into this ImageView. 
    * @param imageLoader 
    *   ImageLoader that will be used to make the request. 
    */ 

    public void setImageUrl(String url, ImageLoader imageLoader) { 
     mUrl = url; 
     mImageLoader = imageLoader; 
     // The URL has potentially changed. See if we need to load it. 
     loadImageIfNecessary(false); 
    } 

    /** 
    * Sets the default image resource ID to be used for this view until the 
    * attempt to load it completes. 
    */ 
    public void setDefaultImageResId(int defaultImage) { 
     mDefaultImageId = defaultImage; 
    } 

    /** 
    * Sets the error image resource ID to be used for this view in the event 
    * that the image requested fails to load. 
    */ 
    public void setErrorImageResId(int errorImage) { 
     mErrorImageId = errorImage; 
    } 

    /** 
    * Loads the image for the view if it isn't already loaded. 
    * 
    * @param isInLayoutPass 
    *   True if this was invoked from a layout pass, false otherwise. 
    */ 
    private void loadImageIfNecessary(final boolean isInLayoutPass) { 
     final int width = getWidth(); 
     int height = getHeight(); 

     boolean isFullyWrapContent = getLayoutParams() != null 
       && getLayoutParams().height == LayoutParams.WRAP_CONTENT 
       && getLayoutParams().width == LayoutParams.WRAP_CONTENT; 
     // if the view's bounds aren't known yet, and this is not a 
     // wrap-content/wrap-content 
     // view, hold off on loading the image. 
     if (width == 0 && height == 0 && !isFullyWrapContent) { 
      return; 
     } 

     // if the URL to be loaded in this view is empty, cancel any old 
     // requests and clear the 
     // currently loaded image. 
     if (TextUtils.isEmpty(mUrl)) { 
      if (mImageContainer != null) { 
       mImageContainer.cancelRequest(); 
       mImageContainer = null; 
      } 
      setDefaultImageOrNull(); 
      return; 
     } 

     // if there was an old request in this view, check if it needs to be 
     // canceled. 
     if (mImageContainer != null && mImageContainer.getRequestUrl() != null) { 
      if (mImageContainer.getRequestUrl().equals(mUrl)) { 
       // if the request is from the same URL, return. 
       return; 
      } else { 
       // if there is a pre-existing request, cancel it if it's 
       // fetching a different URL. 
       mImageContainer.cancelRequest(); 
       setDefaultImageOrNull(); 
      } 
     } 

     // The pre-existing content of this view didn't match the current URL. 
     // Load the new image 
     // from the network. 
     ImageContainer newContainer = mImageLoader.get(mUrl, 
       new ImageListener() { 
        @Override 
        public void onErrorResponse(VolleyError error) { 
         if (mErrorImageId != 0) { 
          setImageResource(mErrorImageId); 
         } 

         if (mObserver != null) { 
          mObserver.onError(); 
         } 
        } 

        @Override 
        public void onResponse(final ImageContainer response, 
              boolean isImmediate) { 
         // If this was an immediate response that was delivered 
         // inside of a layout 
         // pass do not set the image immediately as it will 
         // trigger a requestLayout 
         // inside of a layout. Instead, defer setting the image 
         // by posting back to 
         // the main thread. 
         if (isImmediate && isInLayoutPass) { 
          post(new Runnable() { 
           @Override 
           public void run() { 
            onResponse(response, false); 
           } 
          }); 
          return; 
         } 

         int bWidth = 0, bHeight = 0; 
         if (response.getBitmap() != null) { 

          setImageBitmap(response.getBitmap()); 
          bWidth = response.getBitmap().getWidth(); 
          bHeight = response.getBitmap().getHeight(); 
          adjustImageAspect(bWidth, bHeight); 

         } else if (mDefaultImageId != 0) { 
          setImageResource(mDefaultImageId); 
         } 

         if (mObserver != null) { 
          mObserver.onSuccess(); 

         } 
        } 
       }); 

     // update the ImageContainer to be the new bitmap container. 
     mImageContainer = newContainer; 

    } 

    private void setDefaultImageOrNull() { 
     if (mDefaultImageId != 0) { 
      setImageResource(mDefaultImageId); 
     } else { 
      setImageBitmap(null); 
     } 
    } 

    @Override 
    protected void onLayout(boolean changed, int left, int top, int right, 
          int bottom) { 
     super.onLayout(changed, left, top, right, bottom); 
     loadImageIfNecessary(true); 
    } 

    @Override 
    protected void onDetachedFromWindow() { 
     if (mImageContainer != null) { 
      // If the view was bound to an image request, cancel it and clear 
      // out the image from the view. 
      mImageContainer.cancelRequest(); 
      setImageBitmap(null); 
      // also clear out the container so we can reload the image if 
      // necessary. 
      mImageContainer = null; 
     } 
     super.onDetachedFromWindow(); 
    } 

    @Override 
    protected void drawableStateChanged() { 
     super.drawableStateChanged(); 
     invalidate(); 
    } 

    /* 
    * Adjusting imageview height 
    * */ 
    private void adjustImageAspect(int bWidth, int bHeight) { 
     LinearLayout.LayoutParams params = (LayoutParams) getLayoutParams(); 

     if (bWidth == 0 || bHeight == 0) 
      return; 

     int swidth = getWidth(); 
     int new_height = 0; 
     new_height = swidth * bHeight/bWidth; 
     params.width = swidth; 
     params.height = new_height; 
     setLayoutParams(params); 
    } 
} 

la MainActivity.java

package com.example.asro9.customfeed; 

import android.annotation.SuppressLint; 
import android.app.Activity; 
import android.graphics.Color; 
import android.graphics.drawable.ColorDrawable; 
import android.os.Bundle; 
import android.view.Menu; 
import android.widget.ListView; 
import org.json.JSONException; 
import java.util.ArrayList; 
import java.util.List; 
import Adapter.FeedListAdapter; 
import CustomFeed.AppController; 
import Data.FeedItem; 
import com.android.volley.Cache; 
import com.android.volley.Cache.Entry; 
import com.android.volley.Request.Method; 
import com.android.volley.Response; 
import com.android.volley.VolleyError; 
import com.android.volley.VolleyLog; 
import com.android.volley.toolbox.JsonObjectRequest; 
import java.io.UnsupportedEncodingException; 



import org.json.JSONArray; 

import org.json.JSONObject; 



public class MainActivity extends Activity { 
    private static final String TAG = MainActivity.class.getSimpleName(); 
    private ListView listView; 
    private FeedListAdapter listAdapter; 
    private List<FeedItem> feedItems; 
    private String URL_FEED = "http://api.androidhive.info/feed/feed.json"; 

    @SuppressLint("NewApi") 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     listView = (ListView) findViewById(R.id.list); 

     feedItems = new ArrayList<FeedItem>(); 

     listAdapter = new FeedListAdapter(this, feedItems); 
     listView.setAdapter(listAdapter); 

     // These two lines not needed, 
     // just to get the look of facebook (changing background color & hiding the icon) 
     getActionBar().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#3b5998"))); 
     getActionBar().setIcon(
       new ColorDrawable(getResources().getColor(android.R.color.transparent))); 

     // We first check for cached request 
     Cache cache = AppController.getInstance().getRequestQueue().getCache(); 
     Entry entry = cache.get(URL_FEED); 
     if (entry != null) { 
      // fetch the data from cache 
      try { 
       String data = new String(entry.data, "UTF-8"); 
       try { 
        parseJsonFeed(new JSONObject(data)); 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } catch (UnsupportedEncodingException e) { 
       e.printStackTrace(); 
      } 

     } else { 
      // making fresh volley request and getting json 
      JsonObjectRequest jsonReq = new JsonObjectRequest(Method.GET, 
        URL_FEED, null, new Response.Listener<JSONObject>() { 

       @Override 
       public void onResponse(JSONObject response) { 
        VolleyLog.d(TAG, "Response: " + response.toString()); 
        if (response != null) { 
         parseJsonFeed(response); 
        } 
       } 
      }, new Response.ErrorListener() { 

       @Override 
       public void onErrorResponse(VolleyError error) { 
        VolleyLog.d(TAG, "Error: " + error.getMessage()); 
       } 
      }); 

      // Adding request to volley request queue 
      AppController.getInstance().addToRequestQueue(jsonReq); 
     } 

    } 

    /** 
    * Parsing json reponse and passing the data to feed view list adapter 
    * */ 
    private void parseJsonFeed(JSONObject response) { 
     try { 
      JSONArray feedArray = response.getJSONArray("feed"); 

      for (int i = 0; i < feedArray.length(); i++) { 
       JSONObject feedObj = (JSONObject) feedArray.get(i); 

       FeedItem item = new FeedItem(); 
       item.setId(feedObj.getInt("id")); 
       item.setName(feedObj.getString("name")); 

       // Image might be null sometimes 
       String image = feedObj.isNull("image") ? null : feedObj 
         .getString("image"); 
       item.setImge(image); 
       item.setStatus(feedObj.getString("status")); 
       item.setProfilePic(feedObj.getString("profilePic")); 
       item.setTimeStamp(feedObj.getString("timeStamp")); 

       // url might be null sometimes 
       String feedUrl = feedObj.isNull("url") ? null : feedObj 
         .getString("url"); 
       item.setUrl(feedUrl); 

       feedItems.add(item); 
      } 

      // notify data changes to list adapater 
      listAdapter.notifyDataSetChanged(); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 

} 

AppController.java

package CustomFeed; 

import android.app.Application; 
import android.text.TextUtils; 

import com.android.volley.Request; 
import com.android.volley.RequestQueue; 
import com.android.volley.toolbox.ImageLoader; 
import com.android.volley.toolbox.Volley; 

import Volly.LruBitmapCache; 

/** 
* Created by asro9 on 3/9/2016. 
*/ 
public class AppController extends Application { 

    public static final String TAG = AppController.class.getSimpleName(); 

    private RequestQueue mRequestQueue; 
    private ImageLoader mImageLoader; 
    LruBitmapCache mLruBitmapCache; 

    private static AppController mInstance; 

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

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

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

     return mRequestQueue; 
    } 

    public ImageLoader getImageLoader() { 
     getRequestQueue(); 
     if (mImageLoader == null) { 
      getLruBitmapCache(); 
      mImageLoader = new ImageLoader(this.mRequestQueue, mLruBitmapCache); 
     } 

     return this.mImageLoader; 
    } 

    public LruBitmapCache getLruBitmapCache() { 
     if (mLruBitmapCache == null) 
      mLruBitmapCache = new LruBitmapCache(); 
     return this.mLruBitmapCache; 
    } 

    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); 
     } 
    } 
} 

feeditem.java

package Data; 

/** 
* Created by asro9 on 3/7/2016. 
*/ 
public class FeedItem { 
    private int id; 
    private String name, status, image, profilePic, timeStamp, url; 

    public FeedItem() { 
    } 

    public FeedItem(int id, String name, String image, String status, 
        String profilePic, String timeStamp, String url) { 
     super(); 
     this.id = id; 
     this.name = name; 
     this.image = image; 
     this.status = status; 
     this.profilePic = profilePic; 
     this.timeStamp = timeStamp; 
     this.url = url; 
    } 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getImge() { 
     return image; 
    } 

    public void setImge(String image) { 
     this.image = image; 
    } 

    public String getStatus() { 
     return status; 
    } 

    public void setStatus(String status) { 
     this.status = status; 
    } 

    public String getProfilePic() { 
     return profilePic; 
    } 

    public void setProfilePic(String profilePic) { 
     this.profilePic = profilePic; 
    } 

    public String getTimeStamp() { 
     return timeStamp; 
    } 

    public void setTimeStamp(String timeStamp) { 
     this.timeStamp = timeStamp; 
    } 

    public String getUrl() { 
     return url; 
    } 

    public void setUrl(String url) { 
     this.url = url; 
    } 
} 

cache de volley LruBitmapCache:

package Volly; 

import android.graphics.Bitmap; 
import android.support.v4.util.LruCache; 
import com.android.volley.toolbox.ImageLoader.ImageCache; 

/** 
* Created by asro9 on 3/7/2016. 
*/ 
public class LruBitmapCache extends LruCache<String, Bitmap> implements 
     ImageCache { 
    public static int getDefaultLruCacheSize() { 
     final int maxMemory = (int) (Runtime.getRuntime().maxMemory()/1024); 
     final int cacheSize = maxMemory/8; 

     return cacheSize; 
    } 

    public LruBitmapCache() { 
     this(getDefaultLruCacheSize()); 
    } 

    public LruBitmapCache(int sizeInKiloBytes) { 
     super(sizeInKiloBytes); 
    } 

    @Override 
    protected int sizeOf(String key, Bitmap value) { 
     return value.getRowBytes() * value.getHeight()/1024; 
    } 

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

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

Répondre

0

L'erreur est explicite, l'accident est ici:

ImageLoader imageLoader = AppController.getInstance().getImageLoader(); 

getInstance retourne null.

+0

je suis désolé mais je suis vraiment un amateuri ne comprends pas ce que vous voulez dire –

+0

Assurez-vous que vous initialisez la variable mInstance dans votre classe Application. Appeler getImageLoader() sur cette instance lance un NPE, donc la conclusion logique est que mInstance est nul. – Francesc