1

Я пытаюсь получить данные JSON и отобразить его в своем ListView с помощью ArrayAdapter. В любом случае, в моем адаптере, я использую Universal Image Loader от https://github.com/nostra13/Android-Universal-Image-Loader, а остальные данные были загружены правильно, за исключением изображений. Некоторые изображения были отображены правильно, некоторые не должны быть на определенном элементе, а некоторые не были полностью загружены.Universal 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) 

Были ли какие-либо настройки, которые я сделал неправильно или пропустил в классе приложений для загрузчика изображений? Я искал одно и то же исключение, но ничто не кажется близким к исправлению. Любая помощь поможет. Большое спасибо!

ответ

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 = нуль & & нуль = objBean.getTitle() & & objBean.getTitle() отделка() длина ()> 0) {...} просто использовать TextUtils, который является статическим методом, как это: если (TextUtils.isEmpty (objBean.getTitle);

===========

!

Update

===========

О Ваш вопрос касается отображаются прогрессбар на верхней части изображения: Это простой и сложный :) Есть два способа, первый путь основанный на вашем коде: 1-define интерфейс внутри класса 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

Wow! Это сработало! Я использовал ваш класс ImageDownloader в своем классе приложения и его методе displayImage. Плюс я люблю округленные углы! Большое спасибо. Но мне интересно, почему мои настройки не работают? Это кеш? –

+0

Я помню, что у меня были подобные проблемы, когда я начал интегрировать эту библиотеку в свое приложение в своем первом приложении. Теперь я использую его в своем четвертом приложении, и это самый оптимизированный вариант. Об установках я понятия не имею! :( – Hesam

+0

Я понимаю, и это первое мое приложение, использующее UIL, поэтому я не был уверен, какие оптимальные настройки использовать. Действительно благодарен за это! Кстати, как я могу назвать слушателя для displayImage? как бы использовать его для моего индикатора выполнения. –