图像和列表视图(异步)
Images and listviews (Asynchronous)
我有一个 Listview,它将为每个项目包含一个不同的图像。我按照这个 tutorial 解释了如何实现所有的东西。
在测试我的应用程序时,我发现每个项目同时显示每个图像几毫秒,并且显示很多次,这让我的应用程序崩溃了。我看不出我哪里错了。这是我的代码:
ShowItemAdapter.java
public class ShowItemsAdapter extends ArrayAdapter<Show> {
private ArrayList<Show> shows;
private Context context;
private LayoutInflater inflater;
public class ViewHolder{
public TextView title;
public ImageView image;
}
public ShowItemsAdapter(Context context, List<Show> showArray, List<Bitmap> images)
{
super(context, R.layout.item_shows, showArray);
shows = (ArrayList) showArray;
this.context = context;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rootView = convertView;
ViewHolder holder;
if(convertView == null)
{
rootView = inflater.inflate(R.layout.item_shows, parent, false);
}
holder = new ViewHolder();
holder.image = (ImageView) rootView.findViewById(R.id.item_shows_image);
holder.title = (TextView) rootView.findViewById(R.id.item_shows_title);
holder.title.setText(shows.get(position).getTitle());
ImageFactory imageFactory = new ImageFactory();
imageFactory.setParameters(context, shows.get(position).getImageURL(), holder.image);
return rootView;
}
ImageFactory.java
public class ImageFactory {
public static final String IMAGE = "IMAGE";
private ReceiveImageService receiveImageService;
private Intent intentService;
private ImageReceivedConfirmerReceiver imageReceivedConfirmerReceiver = new ImageReceivedConfirmerReceiver();
private Bitmap image;
private ImageView imageView;
private String url;
private Context context;
public ImageFactory(){}
public void setParameters(Context context, String url, ImageView imageView)
{
this.context = context;
this.imageView = imageView;
context.registerReceiver(
imageReceivedConfirmerReceiver,
new IntentFilter(ImageFactory.IMAGE)
);
this.url = url;
//Creation of the service and adding request
intentService = new Intent(context, ReceiveImageService.class);
intentService.putExtra("URL", url);
context.startService(intentService);
context.bindService(intentService, receiveImageServiceConnection, Context.BIND_AUTO_CREATE);
}
private void displayImage(){
imageView.setImageBitmap(image);
}
private ServiceConnection receiveImageServiceConnection = new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
ReceiveImageService.ReceiveImageBinder binder = (ReceiveImageService.ReceiveImageBinder)service;
//get service
receiveImageService = binder.getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
private class ImageReceivedConfirmerReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(receiveImageService != null)
{
//Receive the array of data
image = receiveImageService.getImage();
displayImage();
}
}
}
}
ReceiveImageService.java
public class ReceiveImageService extends IntentService {
private Connection connectionToServer;
private final IBinder receiveImageBinder = new ReceiveImageBinder();
private final static String BASE_URL = "http://www.readyo.linux.efrei.fr/";
private Bitmap image;
public ReceiveImageService(){super("ReceiveImageService");}
@Override
protected void onHandleIntent(Intent intent) {
String URL = BASE_URL + intent.getStringExtra("URL");
image = reachData(URL);
sendFinishAlert();
}
private Bitmap reachData(String URL) {
HttpURLConnection urlConnection = null;
try {
URL url = new URL(URL);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setUseCaches(true);
urlConnection.addRequestProperty("Cache-Control", "max-age=0");
// handle issues
if (urlConnection.getResponseCode() != 200) {
throw new Exception("Status Error CODE : " + urlConnection.getResponseCode());
}
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
Bitmap bitmap = BitmapFactory.decodeStream(in);
return bitmap;
}catch (Exception e)
{
if(BuildConfig.DEBUG) Log.e("DEBUG", e.getMessage());
//On notifie l'activité qu'une erreur de connexion a eu lieu
//sendBroadcast(new Intent(AbstractNavigationFragment.ERROR_ACTION));
}
finally {
if(urlConnection != null)
urlConnection.disconnect();
}
return null;
}
protected void sendFinishAlert() {
Intent intent = new Intent(ImageFactory.IMAGE);
sendBroadcast(intent);
}
public Bitmap getImage()
{
return image;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent,flags,startId);
}
//BINDER
private ReceiveImageService getInstance()
{
return this;
}
@Override
public IBinder onBind(Intent intent) {
return receiveImageBinder;
}
@Override
public boolean onUnbind(Intent intent){
return false;
}
public class ReceiveImageBinder extends Binder {
public ReceiveImageService getService() {
return ReceiveImageService.this;
}
}
}
我有一个 Listview,它将为每个项目包含一个不同的图像。我按照这个 tutorial 解释了如何实现所有的东西。
在测试我的应用程序时,我发现每个项目同时显示每个图像几毫秒,并且显示很多次,这让我的应用程序崩溃了。我看不出我哪里错了。这是我的代码:
ShowItemAdapter.java
public class ShowItemsAdapter extends ArrayAdapter<Show> {
private ArrayList<Show> shows;
private Context context;
private LayoutInflater inflater;
public class ViewHolder{
public TextView title;
public ImageView image;
}
public ShowItemsAdapter(Context context, List<Show> showArray, List<Bitmap> images)
{
super(context, R.layout.item_shows, showArray);
shows = (ArrayList) showArray;
this.context = context;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rootView = convertView;
ViewHolder holder;
if(convertView == null)
{
rootView = inflater.inflate(R.layout.item_shows, parent, false);
}
holder = new ViewHolder();
holder.image = (ImageView) rootView.findViewById(R.id.item_shows_image);
holder.title = (TextView) rootView.findViewById(R.id.item_shows_title);
holder.title.setText(shows.get(position).getTitle());
ImageFactory imageFactory = new ImageFactory();
imageFactory.setParameters(context, shows.get(position).getImageURL(), holder.image);
return rootView;
}
ImageFactory.java
public class ImageFactory {
public static final String IMAGE = "IMAGE";
private ReceiveImageService receiveImageService;
private Intent intentService;
private ImageReceivedConfirmerReceiver imageReceivedConfirmerReceiver = new ImageReceivedConfirmerReceiver();
private Bitmap image;
private ImageView imageView;
private String url;
private Context context;
public ImageFactory(){}
public void setParameters(Context context, String url, ImageView imageView)
{
this.context = context;
this.imageView = imageView;
context.registerReceiver(
imageReceivedConfirmerReceiver,
new IntentFilter(ImageFactory.IMAGE)
);
this.url = url;
//Creation of the service and adding request
intentService = new Intent(context, ReceiveImageService.class);
intentService.putExtra("URL", url);
context.startService(intentService);
context.bindService(intentService, receiveImageServiceConnection, Context.BIND_AUTO_CREATE);
}
private void displayImage(){
imageView.setImageBitmap(image);
}
private ServiceConnection receiveImageServiceConnection = new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
ReceiveImageService.ReceiveImageBinder binder = (ReceiveImageService.ReceiveImageBinder)service;
//get service
receiveImageService = binder.getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
private class ImageReceivedConfirmerReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(receiveImageService != null)
{
//Receive the array of data
image = receiveImageService.getImage();
displayImage();
}
}
}
}
ReceiveImageService.java
public class ReceiveImageService extends IntentService {
private Connection connectionToServer;
private final IBinder receiveImageBinder = new ReceiveImageBinder();
private final static String BASE_URL = "http://www.readyo.linux.efrei.fr/";
private Bitmap image;
public ReceiveImageService(){super("ReceiveImageService");}
@Override
protected void onHandleIntent(Intent intent) {
String URL = BASE_URL + intent.getStringExtra("URL");
image = reachData(URL);
sendFinishAlert();
}
private Bitmap reachData(String URL) {
HttpURLConnection urlConnection = null;
try {
URL url = new URL(URL);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setUseCaches(true);
urlConnection.addRequestProperty("Cache-Control", "max-age=0");
// handle issues
if (urlConnection.getResponseCode() != 200) {
throw new Exception("Status Error CODE : " + urlConnection.getResponseCode());
}
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
Bitmap bitmap = BitmapFactory.decodeStream(in);
return bitmap;
}catch (Exception e)
{
if(BuildConfig.DEBUG) Log.e("DEBUG", e.getMessage());
//On notifie l'activité qu'une erreur de connexion a eu lieu
//sendBroadcast(new Intent(AbstractNavigationFragment.ERROR_ACTION));
}
finally {
if(urlConnection != null)
urlConnection.disconnect();
}
return null;
}
protected void sendFinishAlert() {
Intent intent = new Intent(ImageFactory.IMAGE);
sendBroadcast(intent);
}
public Bitmap getImage()
{
return image;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent,flags,startId);
}
//BINDER
private ReceiveImageService getInstance()
{
return this;
}
@Override
public IBinder onBind(Intent intent) {
return receiveImageBinder;
}
@Override
public boolean onUnbind(Intent intent){
return false;
}
public class ReceiveImageBinder extends Binder {
public ReceiveImageService getService() {
return ReceiveImageService.this;
}
}
}