1

我想获取JSON数据并使用ArrayAdapter将其显示在我的ListView中。无论如何,在我的适配器中,我使用的是来自https://github.com/nostra13/Android-Universal-Image-Loader的Universal Image Loader,其他数据除了图像以外都正确加载。有些图像显示正确,有些图像不在特定项目上,有些图像没有完全加载。通用ImageLoader java.io.EOFException

这是我的电话片段:

public class SampleFragment extends Fragment implements 
    OnItemClickListener { 

private ListView songsListView; 
private ArrayList<String> list; 
private ArrayAdapter<String> dataAdapter; 
private View rootView; 
private Button selectReferenceSong; 
private Fragment memberFragment; 
private String[] songsArray; 
private ArrayAdapter<String> arrayAdapter; 
private ArrayList<ReferenceTracks> arrayOfList; 
private String bufferString; 

private static final String rssFeed = "https://dl.dropboxusercontent.com/u/32769459/reference_tracks.json"; 

private static final String TAG_MUSIC = "music"; 
private static final String TAG_SONG = "song"; 
private static final String TAG_TITLE = "title"; 
private static final String TAG_ARTIST = "artist"; 
private static final String TAG_DURATION = "duration"; 
private static final String TAG_THUMBURL = "thumb_url"; 

public SampleFragment() { 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    rootView = inflater.inflate(R.layout.sample_layout, container, false); 

    songsListView = (ListView) rootView.findViewById(R.id.songsListView); 
    songsListView.setOnItemClickListener(this); 

    arrayOfList = new ArrayList<ReferenceTracks>(); 

    if (Utility.isNetworkAvailable(getActivity())) { 
     new AsynchronousTask().execute(rssFeed); 
    } else { 
     Toast.makeText(getActivity().getApplicationContext(), 
       "No Network Connection!", Toast.LENGTH_SHORT).show(); 
    } 

    return rootView; 
} 

@Override 
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { 
    // TODO Auto-generated method stub 

} 

/** 
* 
* @Asynchronous class 
*/ 
public class AsynchronousTask extends AsyncTask<String, Void, String> { 

    ProgressDialog pDialog; 
    private RowAdapter objRowAdapter; 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 

     pDialog = new ProgressDialog(getActivity()); 
     pDialog.setMessage("Loading..."); 
     pDialog.setCancelable(false); 
     pDialog.show(); 
    } 

    @Override 
    protected String doInBackground(String... params) { 
     Thread.currentThread().setPriority(Thread.MAX_PRIORITY); 
     return Utility.getJSONString(params[0]); 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     super.onPostExecute(result); 

     if (null != pDialog && pDialog.isShowing()) { 
      pDialog.dismiss(); 
     } 

     if (null == result || result.length() == 0) { 
      Toast.makeText(getActivity().getApplicationContext(), 
        "No data found from web.", Toast.LENGTH_SHORT).show(); 
     } else { 

      try { 
       JSONObject topObject = new JSONObject(result); 
       JSONObject musicObject = topObject.getJSONObject(TAG_MUSIC); 
       JSONArray jsonArray = musicObject.getJSONArray(TAG_SONG); 
       for (int i = 0; i < jsonArray.length(); i++) { 
        JSONObject objJson = jsonArray.getJSONObject(i); 

        ReferenceTracks objItem = new ReferenceTracks(); 
        objItem.setTitle(objJson.getString(TAG_TITLE)); 
        objItem.setArtist(objJson.getString(TAG_ARTIST)); 
        objItem.setDuration(objJson.getString(TAG_DURATION)); 
        objItem.setThumbUrl(objJson.getString(TAG_THUMBURL)); 

        arrayOfList.add(objItem); 

       } 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 

      setAdapterToListview(); 

     } 

    } 

    public void setAdapterToListview() { 
     objRowAdapter = new RowAdapter(getActivity(), R.layout.reference_song_list_item, arrayOfList); 
     songsListView.setAdapter(objRowAdapter); 
    } 
}} 

这是我的自定义适配器:

public class RowAdapter extends ArrayAdapter<ReferenceTracks> { 

private Context activity; 
private ArrayList<ReferenceTracks> items; 
private ReferenceTracks objBean; 
private int row; 
private ImageLoader imageLoader; 
private DisplayImageOptions options; 

public RowAdapter(Context act, int resource, ArrayList<ReferenceTracks> arrayList) { 
    super(act, resource, arrayList); 
    this.activity = act; 
    this.row = resource; 
    this.items = arrayList; 
    imageLoader = ImageLoader.getInstance(); 
} 

@Override 
public View getView(final int position, View convertView, ViewGroup parent) { 
    View view = convertView; 
    ViewHolder holder; 
    if (view == null) { 
     LayoutInflater inflater = (LayoutInflater) activity 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     view = inflater.inflate(row, null); 

     holder = new ViewHolder(); 
     view.setTag(holder); 
    } else { 
     holder = (ViewHolder) view.getTag(); 
    } 

    if ((items == null) || ((position + 1) > items.size())) 
     return view; 

    objBean = items.get(position); 

    holder.tvImage = (ImageView) view.findViewById(R.id.list_image); 
    holder.tvTitle = (TextView) view.findViewById(R.id.title); 
    holder.tvArtist = (TextView) view.findViewById(R.id.artist); 
    holder.tvDuration = (TextView) view.findViewById(R.id.duration); 
    holder.pbar = (ProgressBar) view.findViewById(R.id.progressbar); 

    if (holder.tvImage != null) { 
     if (null != objBean.getThumbUrl() 
       && objBean.getThumbUrl().trim().length() > 0) { 
      final ProgressBar pbar = holder.pbar; 

      imageLoader.destroy(); 
      imageLoader.init(ImageLoaderConfiguration.createDefault(activity)); 
      imageLoader.displayImage(objBean.getThumbUrl(), holder.tvImage, 
        options, new ImageLoadingListener() { 

         @Override 
         public void onLoadingStarted(String imageUri, 
           View view) { 
          // TODO Auto-generated method stub 
          pbar.setVisibility(View.VISIBLE); 
         } 

         @Override 
         public void onLoadingFailed(String imageUri, 
           View view, FailReason failReason) { 
          // TODO Auto-generated method stub 
          pbar.setVisibility(View.INVISIBLE); 
         } 

         @Override 
         public void onLoadingComplete(String imageUri, 
           View view, Bitmap loadedImage) { 
          // TODO Auto-generated method stub 
          pbar.setVisibility(View.INVISIBLE); 
         } 

         @Override 
         public void onLoadingCancelled(String imageUri, 
           View view) { 
          // TODO Auto-generated method stub 

         } 
        }); 

     } else { 
      holder.tvImage.setImageResource(R.drawable.ic_launcher); 
     } 
    } 

    if (holder.tvTitle != null && null != objBean.getTitle() 
      && objBean.getTitle().trim().length() > 0) { 
     holder.tvTitle.setText(Html.fromHtml(objBean.getTitle())); 
    } 
    if (holder.tvArtist != null && null != objBean.getArtist() 
      && objBean.getArtist().trim().length() > 0) { 
     holder.tvArtist.setText(Html.fromHtml(objBean.getArtist())); 
    } 
    if (holder.tvDuration != null && null != objBean.getDuration() 
      && objBean.getDuration().trim().length() > 0) { 
     holder.tvDuration.setText(Html.fromHtml(objBean.getDuration())); 
    } 

    return view; 
} 

public class ViewHolder { 
    public ImageView tvImage; 
    public ProgressBar pbar; 
    public TextView tvTitle, tvArtist, tvDuration; 
}} 

虽然这是我的应用程序类:

public class SampleApplication extends Application { 

@Override 
public void onCreate() { 
    super.onCreate(); 

    DisplayImageOptions displayimageOptions = new DisplayImageOptions.Builder() 
      .showStubImage(R.drawable.ic_stub) 
      .showImageOnFail(R.drawable.ic_error) 
      .showImageForEmptyUri(R.drawable.ic_empty) 
      .cacheInMemory() 
      .cacheOnDisc() 
      .bitmapConfig(Bitmap.Config.RGB_565) 
      .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) 
      .build(); 

    File cacheDir = StorageUtils.getCacheDirectory(getApplicationContext()); 

    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()) 
    .threadPoolSize(4) 
    .threadPriority(Thread.NORM_PRIORITY) 
    .tasksProcessingOrder(QueueProcessingType.LIFO) 
    .defaultDisplayImageOptions(displayimageOptions) 
    .discCacheSize(50 * 1024 * 1024) 
    .discCacheFileCount(1000000) 
    .memoryCache(new WeakMemoryCache()) 
     .build(); 
    ImageLoader.getInstance().init(config); 
}} 

这也是日志:

06-24 11:18:12.935: E/ImageLoader(6428): null 
06-24 11:18:12.935: E/ImageLoader(6428): java.io.EOFException 
06-24 11:18:12.935: E/ImageLoader(6428): at libcore.io.Streams.readAsciiLine(Streams.java:203) 
06-24 11:18:12.935: E/ImageLoader(6428): at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:561) 
06-24 11:18:12.935: E/ImageLoader(6428): at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:801) 
06-24 11:18:12.935: E/ImageLoader(6428): at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:274) 
06-24 11:18:12.935: E/ImageLoader(6428): at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:479) 
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStreamFromNetwork(BaseImageDownloader.java:113) 
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStream(BaseImageDownloader.java:84) 
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.getImageStream(BaseImageDecoder.java:84) 
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.decode(BaseImageDecoder.java:73) 
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.decodeImage(LoadAndDisplayImageTask.java:290) 
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:250) 
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:131) 
06-24 11:18:12.935: E/ImageLoader(6428): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
06-24 11:18:12.935: E/ImageLoader(6428): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
06-24 11:18:12.935: E/ImageLoader(6428): at java.lang.Thread.run(Thread.java:856) 

我的应用程序类是否有任何设置错误或错过了imageloader?我一直在寻找相同的例外,但似乎没有接近修复。任何帮助都可以。非常感谢!

回答

3

我正在使用通用图像加载程序很长一段时间。所以,我更喜欢将它设置在一个类中,然后我的应用程序就可以简单地访问它。

这是通用图像加载器的设置类。我有一个实用程序包,这个类是在这个包下。您可以通过在onLoadingComplete()中注释掉线条来制作图像曲线的角点。

public class ImageDownloader { 

    private static final String TAG = "ImageDownloader"; 
    public static final String DIRECTORY_NAME = "YOUR_DIRECTORY_NAME"; 

    private static ImageDownloader instance = null; 
    private ImageLoader imageLoader; 

    protected ImageDownloader(Context context) { 
     // Exists only to defeat instantiation. 
     configImageDownloader(context); 
    } 

    public static ImageDownloader getInstance(Context context) { 
     if(instance == null) { 
      instance = new ImageDownloader(context); 
     } 
     return instance; 
    } 

    /** 
    * This constructor will configure loader object in order to display image. 
    * @param context 
    */ 
    private void configImageDownloader(Context context) { 

     File cacheDir = StorageUtils.getOwnCacheDirectory(context, DIRECTORY_NAME + "/Cache"); 

     // Get singleton instance of ImageLoader 
     imageLoader = ImageLoader.getInstance(); 

     // Create configuration for ImageLoader (all options are optional) 
     ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context).denyCacheImageMultipleSizesInMemory() 
       .memoryCache(new UsingFreqLimitedMemoryCache(4 * 1024 * 1024)) 
       .discCache(new UnlimitedDiscCache(cacheDir)) 
       .discCacheFileNameGenerator(new HashCodeFileNameGenerator()) 
       .defaultDisplayImageOptions(
         new DisplayImageOptions.Builder() 
           .showStubImage(R.drawable.ic_default_logo) 
           .resetViewBeforeLoading() 
           .cacheInMemory() 
           .cacheOnDisc() 
           .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) 
           .build()) 
       .tasksProcessingOrder(QueueProcessingType.FIFO) 
       .build(); 

     // Initialize ImageLoader with created configuration. 
     imageLoader.init(config); 
    } 


    public void displayImage(final ImageView imageView, String imageURI) { 
     if(imageView == null || imageURI == null) { 
      Log.e(TAG, "Either of image view or image uri is null"); 
      return; 
     } 

     // Load and display image 
     imageLoader.displayImage(imageURI, imageView, new ImageLoadingListener() { 

      @Override 
      public void onLoadingStarted(String imageUri, View view) {} 

      @Override 
      public void onLoadingFailed(String imageUri, View view, FailReason failReason) {} 

      @Override 
      public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { 
//    Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); 
//    imageView.setImageBitmap(getRoundedCornerBitmap(bitmap, 30)); 
      } 

      @Override 
      public void onLoadingCancelled(String imageUri, View view) {} 
     }); 
    } 

    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) { 
     Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); 
     Canvas canvas = new Canvas(output); 

     final int color = 0xff424242; 
     final Paint paint = new Paint(); 
     final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); 
     final RectF rectF = new RectF(rect); 
     final float roundPx = pixels; 

     paint.setAntiAlias(true); 
     canvas.drawARGB(0, 0, 0, 0); 
     paint.setColor(color); 
     canvas.drawRoundRect(rectF, roundPx, roundPx, paint); 

     paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); 
     canvas.drawBitmap(bitmap, rect, rect, paint); 

     return output; 
    } 
} 

在你的适配器类,首先你需要将所有定义为if (view == null) {...}方法。我的样品适配器是这样的。你可以忽略我的监听器,这是因为我在每一行中都有一个按钮。

public class MyCrowdAdapter extends BaseAdapter { 

    public interface OnCrowdRemoveUserListener { 
     public void OnRemoveUserClicked(User user); 
    } 

    private final String TAG = "*** MyCrowdAdapter ***"; 

    private Context context; 
    private OnCrowdRemoveUserListener listener; 
    private LayoutInflater myInflater; 
    private ImageDownloader imageDownloader; 
    private List<User> userList; 

    public MyCrowdAdapter(Context context) { 
     this.context = context; 
     myInflater = LayoutInflater.from(context); 

     imageDownloader = ImageDownloader.getInstance(context); 
    } 

    public void setData(List<User> userList) { 
     this.userList = userList; 

     Log.i(TAG, "List passed to the adapter."); 
    } 

    @Override 
    public int getCount() { 
     try { 
      return userList.size(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return 0; 
     } 
    } 

    @Override 
    public Object getItem(int position) { 
     return null; 
    } 

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

    @Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 
     ViewHolder holder; 

     if (convertView == null) { 
      convertView = myInflater.inflate(R.layout.list_my_crowd_row, null); 
      holder = new ViewHolder(); 

      Typeface font = Typeface.createFromAsset(context.getAssets(), "fonts/ITCAvantGardeStd-Demi.ttf"); 
      holder.tvUserName = (TextView) convertView.findViewById(R.id.tvUserName); 
      holder.tvUserName.setTypeface(font); 
      holder.ivPicture = (ImageView) convertView.findViewById(R.id.ivPicture); 
      holder.btnRemove = (Button) convertView.findViewById(R.id.btnRemove); 
      holder.btnRemove.setFocusable(false); 
      holder.btnRemove.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        Integer pos = (Integer)v.getTag(); 
        Log.i(TAG, "Item: " + pos); 
        listener.OnRemoveUserClicked(userList.get(pos)); 
       } 
      }); 

      convertView.setTag(holder); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     holder.btnRemove.setTag(position); 
     holder.tvUserName.setText(userList.get(position).getFirstName()); 
     imageDownloader.displayImage(holder.ivPicture, userList.get(position).getProfilePictureUrl()); 

     return convertView; 
    } 

    public void setOnRemoveClickedListener(OnCrowdRemoveUserListener listener) { 
     this.listener = listener; 
    } 

    static class ViewHolder { 
     TextView tvUserName; 
     ImageView ivPicture; 
     Button btnRemove; 
    } 
} 

一个建议,而不是验证这样的:!。。 如果(holder.tvTitle = NULL & &空= objBean.getTitle() & & objBean.getTitle()修剪()长度( )> 0){...} 简单地使用TextUtils这是静态方法,像这样: 如果(TextUtils.isEmpty(objBean.getTitle);

===========

更新

===========

关于你的问题方面显示图像的顶部进度: 它的简单和复杂的:)有两种方式,第一个 的方法是根据您的代码: 1 - 在ImageDownloader类中定义一个接口,如适配器内的我的接口。应该是这样的:

public interface OnImageDownloaderListener { 
    public void OnDownloadStarted(); 
    public void OnDownloadFinished(); 
} 

2-声明它在decleration部分

OnImageDownloaderListener listener; 

3-更改thosr两个侦听这样

@Override 
      public void onLoadingStarted(String imageUri, View view) { 
     listener.OnDownloadStarted(); 
} 

      @Override 
      public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { 
//    Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); 
//    imageView.setImageBitmap(getRoundedCornerBitmap(bitmap, 30)); 
     listener.OnDownloadFinished(); 
      } 

4-添加此方法来ImageDownloader类

public void setOnImageDownloaderListener(OnImageDownloaderListener listener) { 
     this.listener = listener; 
    } 

5-适配器和这条线之下:

imageDownloader = ImageDownloader.getInstance(context); 

实现这两个methodes这样的:

imageDownloader.setOnImageDownloaderListener(new ImageDownloader.OnImageDownloaderListener{ 
    @Override 
    public void OnDownloadStarted() { 
     pbar.start(); 
    } 

    @Override 
    public void OnDownloadFinished(){ 
     pbar.stop(); 
    } 
} 
); 

它应该帮助你。但是,如果我是你,我会采用第二种方法创建新组件。该组件包含两个视图,一个图像视图和一个顶部的进度条(与当前相同)。然后在该组件类中添加上述所有方法。因此,通过您的应用程序,您可以在任何想要的活动中添加视图并传递URL,然后组件负责显示进度条并停止它。根据你的代码,如果你有10个similr活动,你需要复制/粘贴上面的代码。

希望它可以帮助你:)

+0

哇!有效!我在我的应用程序类和它的displayImage方法中使用了ImageDownloader类。另外我喜欢圆角!非常感谢。但是我很好奇什么让我的设置不起作用?它是缓存吗? –

+0

我记得当我在第一个应用程序中开始将这个库集成到我的应用程序时,我遇到了类似的问题。现在,我在第四个应用程序中使用它,这是迄今为止最优化的一个。关于设置我不知道! :( – Hesam

+0

我明白了,这也是我的第一个使用UIL的应用程序,所以我不确定使用哪个最佳设置。真的非常感谢!顺便说一下,我如何调用displayImage的监听器?喜欢用它为我的进度条。 –