从外部URL将图像加载到列表视图中

时间:2014-06-10 18:05:28

标签: android image listview url android-listview

我正在尝试通过调用各自的URL来加载列表视图中的图像。我通过拨打在线网络服务获取网址。我的应用程序因NullPointerException而崩溃。

这是我的listview适配器

public class NewsListingActivity extends ListActivity{

final Context context = this;
//NewsItem currentNewsItem;
Category currentCategory;
View view;
NewsItems myNewsItemList = new NewsItems();
public JSONArray newsItems;
public LinkedList<NewsItem> m_newsItems = null;
public NewsItemAdapter m_adapter;
public Runnable viewNewsItems;
public ProgressDialog m_ProgressDialog = null; 
public ListView lv;
NewsItem o;
URL url;
ImageLoader imageLoader;
Bitmap  bmImg; 
public String [] currentNewsItem;


// called when activity is first created

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_newslist);

    //Recieves a Seriablzble Object passed from previous activity - with the tag selectedBook
    currentCategory = (Category) getIntent().getSerializableExtra("selectedCategory");

    final ListView lv = getListView(); //find listview in activity layout
    lv.setTextFilterEnabled(true);  
    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> list, View v, int position, long id) {
            //Log.v("test","Item clicked: "+ position); 
            //on click proceed to the next activity while passing an object of the clicked item - Book
            Intent intent = new Intent(getApplicationContext() , NewsItemView.class);
            intent.putExtra("selectedCategory", m_adapter.getItem(position)); // pass Object - Book
            startActivity(intent);        
        }
     });

    //Log.v("test","currentCategory is: " + currentCategory.getCategoryName()+ " "+ currentCategory.getId());
    setUpViews();
}

    private void setUpViews(){
        final ListView lv = getListView(); //find listview in activity layout
        lv.setTextFilterEnabled(true);  
        m_newsItems = new LinkedList<NewsItem>(); //create LinkedList of type NewsItem
        this.m_adapter = new NewsItemAdapter(this, R.layout.row_news, m_newsItems); // ItemListView Holder
        setListAdapter(this.m_adapter); //attach adapter to ListView

        viewNewsItems = new Runnable(){
            @Override
            public void run() {
                getNewsItems(); // run in background 
            }
        };
        //create a thread and a progress dialog to handle processes in background
        //avoid lagging or freezing app-phone
        Thread thread =  new Thread(null, viewNewsItems, "MagentoBackground");
        thread.start();
        m_ProgressDialog = ProgressDialog.show(NewsListingActivity.this,    
              "Please wait...", "Retrieving data ...", true);   
    }  

private Runnable returnRes = new Runnable() {
    // loop through list of type newsItems to update UI 
    @Override
    public void run() {
        if(m_newsItems != null && m_newsItems.size() > 0){
            m_adapter.notifyDataSetChanged();
            for(int i=0;i<m_newsItems.size();i++)
            m_adapter.add(m_newsItems.get(i));
        }
        m_ProgressDialog.dismiss();
        m_adapter.notifyDataSetChanged();
    }
};



private void getNewsItems(){
    try{

        updateNewsItemList();

        m_newsItems = myNewsItemList.getNewsItemList();
        Thread.sleep(5000);
        Log.i("ARRAY", ""+ m_newsItems.size());
      } catch (Exception e) { 
        Log.e("BACKGROUND_PROC", e.getMessage());
      }
      runOnUiThread(returnRes);
  }

//Contacts server to retrive JSON object containing all BOOKS and their related information
public void updateNewsItemList(){
    //String request = "http://xxxxx/RestServiceImpl.svc/GetNews/1";
    String request= "http://xxxxxx/RestServiceImpl.svc/GetNews/" + currentCategory.getId();
    // Creating JSON Parser instance
    JSONParser jParser = new JSONParser();
    // getting JSON string from URL
    JSONObject json = jParser.getJSONFromUrl(request); 
    Log.v("test","request is made");

    try {
        // Getting Array of Contacts
        newsItems = json.getJSONArray("GetNewsResult");
        //Log.v("test","content is: "+ newsItems.length());
        // looping through All newsItems
        for(int i = 0; i < newsItems.length(); i++){
        //  Log.v("test","inside loop");

           currentNewsItem = new String[5];
            JSONObject c = newsItems.getJSONObject(i);
            currentNewsItem[0] = c.getString("NewsId"); 
            currentNewsItem[1] = c.getString("NewsCategory");
            currentNewsItem[2] = c.getString("NewsDesc");
            currentNewsItem[3] = "http://xxxxxxxx/CMS/Management/News/Images/" + c.getString("NewsImage");
            currentNewsItem[4] = c.getString("NewsTitle");                                  
            myNewsItemList.getNewsItemList().add(new NewsItem(currentNewsItem));
            currentNewsItem = null; //clear array after each loop



        }  
    } catch (JSONException e) {
        Log.v("test","no array found");
    }};





//ListView Adapter
private class NewsItemAdapter extends ArrayAdapter<NewsItem> {
    private LinkedList<NewsItem> items;

    public NewsItemAdapter(Context context, int textViewResourceId, LinkedList<NewsItem> items) {
            super(context, textViewResourceId, items);
            this.items = items;
    }

    @Override
    public int getCount() {
            return items.size();
            //return number of items in array
    }

    @Override
    public NewsItem getItem(int position) {
        return items.get(position);
        // return task by passing position
    }

    @Override
    public long getItemId(int position) {
        return position; //return item id by passing position 
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
        View v = convertView;
            if (v == null) {
                LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                v = vi.inflate(R.layout.row_news, null);
            }
             o = items.get(position);
            if (o != null) { //listView attributes - nodes - views
                     TextView newsTitle = (TextView) v.findViewById(R.id.title);
                     ImageView newsImage = (ImageView) v.findViewById(R.id.newsImage);

                     newsTitle.setText(o.getNewsTitle());
                    // Log.v("test","this is url to call: " + o.getNewsImage());
                    imageLoader.DisplayImage(o.getNewsImage(), NewsListingActivity.this, newsImage);

                     /**
                     newsImage.setImageBitmap(bmImg);

                          try {
                               url = new URL(o.getNewsImage());
                               HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                               conn.setDoInput(true);
                               conn.connect();
                               InputStream is = conn.getInputStream();
                               bmImg = BitmapFactory.decodeStream(is);
                               //Here u will set image in imageview
                               newsImage.setImageBitmap(bmImg);
                            } 

                          catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                    */
            }           
            return v;
    }
}

}

这是我的ImageLoader类

public class ImageLoader {

//the simplest in-memory cache implementation. This should be replaced with something like SoftReference or BitmapOptions.inPurgeable(since 1.6)
private HashMap<String, Bitmap> cache=new HashMap<String, Bitmap>();

private File cacheDir;

public ImageLoader(Context context){
    //Make the background thead low priority. This way it will not affect the UI performance
    photoLoaderThread.setPriority(Thread.NORM_PRIORITY-1);

    //Find the dir to save cached images
   if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
        cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"LazyList");
    else
        cacheDir=context.getCacheDir();
    if(!cacheDir.exists())
        cacheDir.mkdirs();
}

final int stub_id=R.drawable.ic_action_search;
public void DisplayImage(String url, Activity activity, ImageView imageView)
{
    if(cache.containsKey(url))
        imageView.setImageBitmap(cache.get(url));
    else
    {
        queuePhoto(url, activity, imageView);
        imageView.setImageResource(stub_id);
    }    
}

private void queuePhoto(String url, Activity activity, ImageView imageView)
{
    //This ImageView may be used for other images before. So there may be some old tasks in the queue. We need to discard them. 
    photosQueue.Clean(imageView);
    PhotoToLoad p=new PhotoToLoad(url, imageView);
    synchronized(photosQueue.photosToLoad){
        photosQueue.photosToLoad.push(p);
        photosQueue.photosToLoad.notifyAll();
    }        
    //start thread if it's not started yet
    if(photoLoaderThread.getState()==Thread.State.NEW)
        photoLoaderThread.start();
}

private Bitmap getBitmap(String url) 
{

    //I identify images by hashcode. Not a perfect solution, good for the demo.
    String filename=String.valueOf(url.hashCode());
    File f=new File(cacheDir, filename);

    //from SD cache
    Bitmap b = decodeFile(f);
    if(b!=null)
        return b;

    //from web
    try {
        Bitmap bitmap=null;
        DataInputStream input = null;
          InputStream is=new URL(url).openStream();
       // String auth = android.util.Base64.encodeToString(("devneoauto" + ":" + "2kk0rnpnpvir")
         //    .getBytes("UTF-8"), android.util.Base64.NO_WRAP);

        HttpClient client = new DefaultHttpClient();
        HttpGet getmethod = new HttpGet(url);

       // getmethod.addHeader("Authorization", "Basic " + auth);
       // getmethod.addHeader("X-ZFWS-Accept", "text/json");

        HttpResponse responseGet = client.execute(getmethod);
        HttpEntity resEntityGet = responseGet.getEntity();

        if (resEntityGet != null) {

            input = new DataInputStream(responseGet.getEntity().getContent());

        }

        OutputStream os = new FileOutputStream(f);
        Utils.CopyStream(input, os);
        os.close();
        bitmap = decodeFile(f);
        return bitmap;
    } catch (Exception ex){
       ex.printStackTrace();
       return null;
    }
}

//decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f){
    try {
        //decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o);

        //Find the correct scale value. It should be the power of 2.
        final int REQUIRED_SIZE=70;
        int width_tmp=o.outWidth, height_tmp=o.outHeight;
        int scale=1;
        while(true){
            if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
                break;
            width_tmp/=2;
            height_tmp/=2;
            scale++;
        }

        //decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize=scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {}
    return null;
}

//Task for the queue
private class PhotoToLoad
{
    public String url;
    public ImageView imageView;
    public PhotoToLoad(String u, ImageView i){
        url=u; 
        imageView=i;
    }
}

PhotosQueue photosQueue=new PhotosQueue();

public void stopThread()
{
    photoLoaderThread.interrupt();
}

//stores list of photos to download
class PhotosQueue
{
    private Stack<PhotoToLoad> photosToLoad=new Stack<PhotoToLoad>();

    //removes all instances of this ImageView
    public void Clean(ImageView image)
    {
        for(int j=0 ;j<photosToLoad.size();){
            if(photosToLoad.get(j).imageView==image)
                photosToLoad.remove(j);
            else
                ++j;
        }
    }
}

class PhotosLoader extends Thread {
    public void run() {
        try {
            while(true)
            {
                //thread waits until there are any images to load in the queue
                if(photosQueue.photosToLoad.size()==0)
                    synchronized(photosQueue.photosToLoad){
                        photosQueue.photosToLoad.wait();
                    }
                if(photosQueue.photosToLoad.size()!=0)
                {
                    PhotoToLoad photoToLoad;
                    synchronized(photosQueue.photosToLoad){
                        photoToLoad=photosQueue.photosToLoad.pop();
                    }
                    Bitmap bmp=getBitmap(photoToLoad.url);
                    cache.put(photoToLoad.url, bmp);
                    if(((String)photoToLoad.imageView.getTag()).equals(photoToLoad.url)){
                        BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad.imageView);
                        Activity a=(Activity)photoToLoad.imageView.getContext();
                        a.runOnUiThread(bd);
                    }
                }
                if(Thread.interrupted())
                    break;
            }
        } catch (InterruptedException e) {
            //allow thread to exit
        }
    }
}

PhotosLoader photoLoaderThread=new PhotosLoader();

//Used to display bitmap in the UI thread
class BitmapDisplayer implements Runnable
{
    Bitmap bitmap;
    ImageView imageView;
    public BitmapDisplayer(Bitmap b, ImageView i){bitmap=b;imageView=i;}
    public void run()
    {
        if(bitmap!=null)
        {
            imageView.setImageBitmap(bitmap);
        }
       else
           imageView.setImageResource(R.drawable.ic_action_search);
    }
}

public void clearCache() {
    //clear memory cache
    cache.clear();        
    //clear SD cache
    File[] files=cacheDir.listFiles();
    for(File f:files)
        f.delete();
}

}

LogCat输出:

06-10 21:29:00.771: E/AndroidRuntime(25339): FATAL EXCEPTION: main
06-10 21:29:00.771: E/AndroidRuntime(25339): Process: com.saeedjoul.hayatnews, PID: 25339
06-10 21:29:00.771: E/AndroidRuntime(25339): java.lang.NullPointerException
06-10 21:29:00.771: E/AndroidRuntime(25339):    at com.saeedjoul.hayatnews.NewsListingActivity$NewsItemAdapter.getView(NewsListingActivity.java:239)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.AbsListView.obtainView(AbsListView.java:2720)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.ListView.makeAndAddView(ListView.java:1801)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.ListView.fillDown(ListView.java:697)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.ListView.fillFromTop(ListView.java:763)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.ListView.layoutChildren(ListView.java:1627)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.AbsListView.onLayout(AbsListView.java:2533)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.View.layout(View.java:15655)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.ViewGroup.layout(ViewGroup.java:4856)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1677)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1531)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.LinearLayout.onLayout(LinearLayout.java:1440)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.View.layout(View.java:15655)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.ViewGroup.layout(ViewGroup.java:4856)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1677)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1531)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.LinearLayout.onLayout(LinearLayout.java:1440)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.View.layout(View.java:15655)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.ViewGroup.layout(ViewGroup.java:4856)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.View.layout(View.java:15655)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.ViewGroup.layout(ViewGroup.java:4856)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1677)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1531)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.LinearLayout.onLayout(LinearLayout.java:1440)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.View.layout(View.java:15655)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.ViewGroup.layout(ViewGroup.java:4856)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.View.layout(View.java:15655)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.ViewGroup.layout(ViewGroup.java:4856)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2284)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2004)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1234)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6467)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.Choreographer.doCallbacks(Choreographer.java:603)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.Choreographer.doFrame(Choreographer.java:573)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.os.Handler.handleCallback(Handler.java:733)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.os.Handler.dispatchMessage(Handler.java:95)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.os.Looper.loop(Looper.java:157)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at android.app.ActivityThread.main(ActivityThread.java:5356)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at java.lang.reflect.Method.invokeNative(Native Method)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at java.lang.reflect.Method.invoke(Method.java:515)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
06-10 21:29:00.771: E/AndroidRuntime(25339):    at dalvik.system.NativeStart.main(Native Method)

记录2

06-10 23:00:46.196: W/System.err(30836): java.net.MalformedURLException: Protocol not found: 162.13.166.28/CMS/Management/News/Images/3.jpg 06-10 23:00:46.196:         W/System.err(30836): at java.net.URL.<init>(URL.java:176) 06-10 23:00:46.196: W/System.err(30836): at java.net.URL.<init>(URL.java:125) 06-10 23:00:46.196: W/System.err(30836): at com.saeedjoul.hayatnews.ImageLoader.getBitmap(ImageLoader.java:88)        06-10 23:00:46.196: W/System.err(30836): at com.saeedjoul.hayatnews.ImageLoader.access$0(ImageLoader.java:72) 06-10 23:00:46.196: W/System.err(30836): at com.saeedjoul.hayatnews.ImageLoader$PhotosLoader.run(ImageLoader.java:197) 06-10 23:00:46.196: W/dalvikvm(30836): threadid=11: thread exiting with uncaught exception (group=0x4183bc08) 06-10 23:00:46.196: E/AndroidRuntime(30836): FATAL EXCEPTION: Thread-31698 06-10 23:00:46.196: E/AndroidRuntime(30836): Process: com.saeedjoul.hayatnews, PID: 30836 06-10 23:00:46.196: E/AndroidRuntime(30836): java.lang.NullPointerException 06-10 23:00:46.196: E/AndroidRuntime(30836): at com.saeedjoul.hayatnews.ImageLoader$PhotosLoader.run(ImageLoader.java:199)

1 个答案:

答案 0 :(得分:0)

它是null,因为您没有从类中实例化imageLoader,因此在此行中为您提供了 NPE imageLoader.DisplayImage(o.getNewsImage(), NewsListingActivity.this, newsImage);

<强>解决方案:

在使用imageLoader方法之前实例化DisplayImage

imageLoader = new ImageLoader(NewsListingActivity.this);
imageLoader.DisplayImage(o.getNewsImage(), NewsListingActivity.this, newsImage);