无法使用 JSON 从列表视图中的 url 加载图像

问题描述 投票:0回答:2

列表视图中的每个元素都包含文本和图像。我可以使用 JSON 从 url 获取文本并显示在列表视图中。我还可以获取图像的 url,但无法在列表中显示它们。这是我的代码:

 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    lv = (ListView) findViewById(R.id.newslist);
    img_url = (TextView) findViewById(R.id.iamge_url);
    contactList = new ArrayList<HashMap<String, Object>>();

    new GetContacts().execute();
}

 private class GetContacts extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... arg0) {
        // Creating service handler class instance
        ServiceHandler sh = new ServiceHandler();

        // Making a request to url and getting response
        String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);

        Log.d("Response: ", "> " + jsonStr);

        if (jsonStr != null) {
            try {
                JSONObject jsonObj = new JSONObject(jsonStr);

                // Getting JSON Array node
                contacts = jsonObj.getJSONArray(TAG_POSTS);




                // looping through All Contacts
                for (int i = 0; i < contacts.length(); i++) {
                  // JSONObject c = contacts.getJSONObject(i);


                   JSONObject posts = contacts.getJSONObject(i);

                   JSONArray attachment = posts.getJSONArray("attachments");
                     for (int j = 0; j< attachment.length(); j++){
                   JSONObject obj = attachment.getJSONObject(j);
                   JSONObject image = obj.getJSONObject("images");

                   JSONObject image_small = image.getJSONObject("tie-small");

                   String  imgurl = image_small.getString("url");  
                    Bitmap picture = getBitmapFromURL(imgurl);

                    HashMap<String, Object> contact = new HashMap<String, Object>();
                    contact.put("image_url", imgurl);  //this image i want to load
                    contact.put("icon", picture);      //this displays fine
                    contact.put(TAG_TITLE, title);     // this displays fine
                    contactList.add(contact);
                     }    

               }

protected void onPostExecute(Void result) {
        super.onPostExecute(result);


        ListAdapter adapter = new SimpleAdapter(MainActivity.this, contactList, R.layout.third_row, 
                new String[] {"image_url",TAG_TITLE,"icon"}, 
new int[] {R.id.iamge_url,R.id.headline3,R.id.imageicon});

        lv.setAdapter(adapter);


    }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        } else {
            Log.e("ServiceHandler", "Couldn't get any data from the url");
        }

        return null;
    }

这是我的方法 getBitmapFromURL() 用于从 url 获取图像:

public static Bitmap getBitmapFromURL(String src) {
    try {
        Log.e("src",src);
        URL url = new URL(src);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoInput(true);
        connection.connect();
        InputStream input = connection.getInputStream();
        Bitmap myBitmap = BitmapFactory.decodeStream(input);
        Log.e("Bitmap","returned");
        return myBitmap;
    } catch (IOException e) {
        e.printStackTrace();
        Log.e("Exception",e.getMessage());
        return null;
    }
}

没有错误。应用程序也不会崩溃,但在列表视图中不会显示图像。我在 logcat 中收到错误消息:

unable to decode stream java.io.filenotfoundexception /android.graphics.bitmap (no such file or directory)

我检查了网址。这是工作。我可以使用 url 在浏览器中查看图像。不知道问题出在哪里。

android json listview
2个回答
0
投票

首先从JSON中获取imageUrl,并使用此方法将其转换为位图。

public static Bitmap getBitmap(String imageUrl)
{
    if (imageUrl != null && !imageUrl.equals("null"))
    {
        Bitmap bmp = null;
        try
        {
            URL url = new URL(imageUrl);
            bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
        } catch (MalformedURLException mue)
        {
            Log.e("Get Thumbnail", "Error retrieving thumbnail");
            mue.printStackTrace();
        } catch (IOException io)
        {
            Log.e("Get Thumbnail", "Error retrieving thumbnail");
            io.printStackTrace();
        }
        return bmp;
    }
    return null;
}

使用它来调整大小(尽管您也可以使用imageview的XML属性来缩放和调整大小)

public static Bitmap getResizedBitmap(Bitmap image)
{
    return Bitmap.createScaledBitmap(image, 175, 175, true);
}

然后在列表视图适配器的

getView()

    // Scale and set the Image
    if (myArrayList.get(position).getImage() == null)
    {
    // set default image if there is no image
        imgThumbnail.setImageResource(R.drawable.placeholder);
    } else {
        imgThumbnail.setImageBitmap(myArrayList.get(position).getImage());
    }

0
投票

您正在从 json 正确获取 URL...使用该 URL 您可以加载您的图像...

首先在AndroidMenifest.xml中添加以下权限

 <!-- Internet Permissions -->
    <uses-permission android:name="android.permission.INTERNET" />
     
    <!-- Permission to write to external storage -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

然后

AndroidLoadImageFromURLActivity.java
package com.example.imagefromurl;
 
import android.app.Activity;
import android.os.Bundle;
import android.widget.ImageView;
 
public class AndroidLoadImageFromURLActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
         
        // Loader image - will be shown before loading image
        int loader = R.drawable.loader;
         
        // Imageview to show
        ImageView image = (ImageView) findViewById(R.id.image);
         
        // Image url
        String image_url = "http://api.androidhive.info/images/sample.jpg";
         
        // ImageLoader class instance
        ImageLoader imgLoader = new ImageLoader(getApplicationContext());
         
        // whenever you want to load an image from url
        // call DisplayImage function
        // url - image url to load
        // loader - loader image, will be displayed before getting image
        // image - ImageView 
        imgLoader.DisplayImage(image_url, loader, image);
    }
}

还有 ImageLoader 类..

//ImageLoader.java
package com.example.imagefromurl;
 
//import statement
  
public class ImageLoader {
  
    MemoryCache memoryCache=new MemoryCache();
    FileCache fileCache;
    private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
    ExecutorService executorService; 
  
    public ImageLoader(Context context){
        fileCache=new FileCache(context);
        executorService=Executors.newFixedThreadPool(5);
    }
  
    int stub_id = R.drawable.ic_launcher;
    public void DisplayImage(String url, int loader, ImageView imageView)
    {
        stub_id = loader;
        imageViews.put(imageView, url);
        Bitmap bitmap=memoryCache.get(url);
        if(bitmap!=null)
            imageView.setImageBitmap(bitmap);
        else
        {
            queuePhoto(url, imageView);
            imageView.setImageResource(loader);
        }
    }
  
    private void queuePhoto(String url, ImageView imageView)
    {
        PhotoToLoad p=new PhotoToLoad(url, imageView);
        executorService.submit(new PhotosLoader(p));
    }
  
    private Bitmap getBitmap(String url)
    {
        File f=fileCache.getFile(url);
  
        //from SD cache
        Bitmap b = decodeFile(f);
        if(b!=null)
            return b;
  
        //from web
        try {
            Bitmap bitmap=null;
            URL imageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            conn.setInstanceFollowRedirects(true);
            InputStream is=conn.getInputStream();
            OutputStream os = new FileOutputStream(f);
            Utils.CopyStream(is, 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*=2;
            }
  
            //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;
        }
    }
  
    class PhotosLoader implements Runnable {
        PhotoToLoad photoToLoad;
        PhotosLoader(PhotoToLoad photoToLoad){
            this.photoToLoad=photoToLoad;
        }
  
        @Override
        public void run() {
            if(imageViewReused(photoToLoad))
                return;
            Bitmap bmp=getBitmap(photoToLoad.url);
            memoryCache.put(photoToLoad.url, bmp);
            if(imageViewReused(photoToLoad))
                return;
            BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);
            Activity a=(Activity)photoToLoad.imageView.getContext();
            a.runOnUiThread(bd);
        }
    }
  
    boolean imageViewReused(PhotoToLoad photoToLoad){
        String tag=imageViews.get(photoToLoad.imageView);
        if(tag==null || !tag.equals(photoToLoad.url))
            return true;
        return false;
    }
  
    //Used to display bitmap in the UI thread
    class BitmapDisplayer implements Runnable
    {
        Bitmap bitmap;
        PhotoToLoad photoToLoad;
        public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;}
        public void run()
        {
            if(imageViewReused(photoToLoad))
                return;
            if(bitmap!=null)
                photoToLoad.imageView.setImageBitmap(bitmap);
            else
                photoToLoad.imageView.setImageResource(stub_id);
        }
    }
  
    public void clearCache() {
        memoryCache.clear();
        fileCache.clear();
    }
  
}

此代码都可以在这里找到。

© www.soinside.com 2019 - 2024. All rights reserved.