diff --git a/app/release/app-release.apk b/app/release/app-release.apk index f5ecce9..58a5bab 100644 Binary files a/app/release/app-release.apk and b/app/release/app-release.apk differ diff --git a/app/src/main/java/com/example/myapplication/ImageLoader.java b/app/src/main/java/com/example/myapplication/ImageLoader.java index 95ed493..3532a70 100644 --- a/app/src/main/java/com/example/myapplication/ImageLoader.java +++ b/app/src/main/java/com/example/myapplication/ImageLoader.java @@ -2,45 +2,104 @@ package com.example.myapplication; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.os.AsyncTask; import android.os.Handler; import android.os.Message; +import android.util.LruCache; import android.widget.ImageView; +import android.widget.ListView; import javax.net.ssl.HttpsURLConnection; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.util.HashSet; +import java.util.Set; public class ImageLoader { private ImageView mImageView; private String murl; - private Handler handler = new Handler(){ - @Override - public void handleMessage(Message msg) { - super.handleMessage(msg); - if(mImageView.getTag().equals(murl)) { - mImageView.setImageBitmap((Bitmap) msg.obj); - } - } - }; + //创建Cache + private LruCache mCaches; + private ListView mListView; + private Set mTask; - public void showImagerByThread(ImageView imageView, final String url){ - mImageView = imageView; - murl = url; - new Thread(){ + public ImageLoader(ListView listView){ + //构造方法 + mListView = listView; + mTask = new HashSet<>(); + //获取最大可用内存 + int maxMemory = (int) Runtime.getRuntime().maxMemory(); + //缓存为内存的四分之一 + int cacheSize = maxMemory / 4; + mCaches = new LruCache(cacheSize){ @Override - public void run() { - super.run(); - Bitmap bitmap = getBitmapFromURL(url); - Message message = Message.obtain(); - message.obj = bitmap; - handler.sendMessage(message); + protected int sizeOf(String key, Bitmap value) { + //每次加入内存缓存的时候进行调用,把value的实际大小放进去 + return value.getByteCount(); } - }.start(); + }; + } + /** + * 增加到缓存 + * @param url + * @param bitmap + */ + public void addBitmapToCache(String url, Bitmap bitmap){ + //判断缓存中是否有这个值 + if(getBitmapFromCache(url) == null){ + mCaches.put(url, bitmap); + } + } + + /** + * 从缓存中读取数据 + * @param url + * @return + */ + public Bitmap getBitmapFromCache(String url){ + //获取缓存的对象 + return mCaches.get(url); + } + +// private Handler handler = new Handler(){ +// @Override +// public void handleMessage(Message msg) { +// super.handleMessage(msg); +// //接受message +// if(mImageView.getTag().equals(murl)) { +// //url相同的时候才设置view,防止图片一样 +// mImageView.setImageBitmap((Bitmap) msg.obj); +// } +// } +// }; +// +// public void showImagerByThread(ImageView imageView, final String url){ +// //把两个值保存给上面的子线程使用 +// mImageView = imageView; +// murl = url; +// new Thread(){ +// @Override +// public void run() { +// super.run(); +// Bitmap bitmap = getBitmapFromURL(url); +// Message message = Message.obtain(); +// message.obj = bitmap; +// //发送message +// handler.sendMessage(message); +// } +// }.start(); +// } + + /** + * 根据url获取图片的Bitmap对象 + * @param urlString + * @return + */ public Bitmap getBitmapFromURL(String urlString){ Bitmap bitmap; InputStream is = null; @@ -62,4 +121,90 @@ public class ImageLoader { } return null; } + + public void showImageByAsyncTask(ImageView imageView,String url){ + //判断缓存中是否有 + Bitmap bitmap = getBitmapFromCache(url); + if(bitmap == null){ + //缓存中没有就去下载 + //new NewsAsyncTask(imageView, url).execute(url); + + //没有就给默认的 + imageView.setImageResource(R.mipmap.ic_launcher); + }else{ + imageView.setImageBitmap(bitmap); + } + + } + + /** + * 停止运行的任务 + */ + public void cancelAllTasks(){ + if(mTask != null){ + for (NewsAsyncTask task : mTask){ + task.cancel(false); + } + } + } + + public void loadImages(int start, int end){ + for (int i = start; i < end; i++) { + String url = NewsAdapter.URLS[i]; + //判断缓存中是否有 + Bitmap bitmap = getBitmapFromCache(url); + if(bitmap == null){ + //缓存中没有就去下载 + //new NewsAsyncTask(imageView, url).execute(url); + NewsAsyncTask task = new NewsAsyncTask(url); + task.execute(url); + mTask.add(task); + }else{ + //imageView.setImageBitmap(bitmap); + ImageView imageView = mListView.findViewWithTag(url); + imageView.setImageBitmap(bitmap); + } + } + } + + /** + * AsyncTask的方式把图片放入view + */ + private class NewsAsyncTask extends AsyncTask{ + + //private ImageView mImageView; + private String murl; + + public NewsAsyncTask(String url){ + //mImageView = imageView; + murl = url; + } + + @Override + protected Bitmap doInBackground(String... strings) { + String url = strings[0]; + //从网络中获取图片 + Bitmap bitmap = getBitmapFromURL(url); + if(bitmap != null){ + //增加到缓存 + addBitmapToCache(url, bitmap); + } + return bitmap; + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + super.onPostExecute(bitmap); + //防止图片重复判断唯一性 +// if(mImageView.getTag().equals(murl)) { +// mImageView.setImageBitmap(bitmap); +// } + ImageView imageView = mListView.findViewWithTag(murl); + imageView.setImageBitmap(bitmap); + if(imageView != null && bitmap != null){ + imageView.setImageBitmap(bitmap); + } + mTask.remove(this); + } + } } diff --git a/app/src/main/java/com/example/myapplication/MainActivity.java b/app/src/main/java/com/example/myapplication/MainActivity.java index ce31731..27a36eb 100644 --- a/app/src/main/java/com/example/myapplication/MainActivity.java +++ b/app/src/main/java/com/example/myapplication/MainActivity.java @@ -30,6 +30,7 @@ public class MainActivity extends AppCompatActivity { setContentView(R.layout.activity_main); mListView = (ListView) findViewById(R.id.new_main); + //点击事件 mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { @@ -60,7 +61,7 @@ public class MainActivity extends AppCompatActivity { @Override protected void onPostExecute(List newBeans) { super.onPostExecute(newBeans); - NewsAdapter adapter = new NewsAdapter(MainActivity.this, newBeans); + NewsAdapter adapter = new NewsAdapter(MainActivity.this, newBeans, mListView); mListView.setAdapter(adapter); } } diff --git a/app/src/main/java/com/example/myapplication/NewBean.java b/app/src/main/java/com/example/myapplication/NewBean.java index a22b342..5f588d9 100644 --- a/app/src/main/java/com/example/myapplication/NewBean.java +++ b/app/src/main/java/com/example/myapplication/NewBean.java @@ -1,7 +1,5 @@ package com.example.myapplication; -import java.util.Date; - public class NewBean { private String id; diff --git a/app/src/main/java/com/example/myapplication/NewsAdapter.java b/app/src/main/java/com/example/myapplication/NewsAdapter.java index 45e00c8..0f97886 100644 --- a/app/src/main/java/com/example/myapplication/NewsAdapter.java +++ b/app/src/main/java/com/example/myapplication/NewsAdapter.java @@ -4,20 +4,33 @@ import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.ImageView; -import android.widget.TextView; +import android.widget.*; import java.util.List; -public class NewsAdapter extends BaseAdapter { +public class NewsAdapter extends BaseAdapter implements AbsListView.OnScrollListener { private List mList; private LayoutInflater mInflater; + private ImageLoader mImageLoader; + private int mstart,mend; + public static String[] URLS; + //是否第一次启动 + private boolean mFirst; - public NewsAdapter(Context context, List data){ + public NewsAdapter(Context context, List data, ListView listView){ + //构造方法 mList = data; mInflater = LayoutInflater.from(context); + mImageLoader = new ImageLoader(listView); + URLS = new String[data.size()]; + for (int i = 0;i < data.size();i++){ + URLS[i] = data.get(i).getPicUrl(); + } + //绑定监听事件 + listView.setOnScrollListener(this); + //初始化值 + mFirst = true; } @Override @@ -53,7 +66,9 @@ public class NewsAdapter extends BaseAdapter { viewHolder.newPic.setImageResource(R.mipmap.ic_launcher); String url = mList.get(position).getPicUrl(); viewHolder.newPic.setTag(url); - new ImageLoader().showImagerByThread(viewHolder.newPic, mList.get(position).getPicUrl()); + //new ImageLoader().showImagerByThread(viewHolder.newPic, mList.get(position).getPicUrl()); + //new ImageLoader().showImageByAsyncTask(viewHolder.newPic, mList.get(position).getPicUrl()); + mImageLoader.showImageByAsyncTask(viewHolder.newPic, mList.get(position).getPicUrl()); viewHolder.newTitle.setText(mList.get(position).getTitle()); viewHolder.newTime.setText(mList.get(position).getTime()); viewHolder.newDesc.setText(mList.get(position).getDesc()); @@ -61,6 +76,30 @@ public class NewsAdapter extends BaseAdapter { return convertView; } + @Override + public void onScrollStateChanged(AbsListView view, int scrollState) { + //滑动状态的时候调用 + if(scrollState == SCROLL_STATE_IDLE){ + //停止滚动的时候 + mImageLoader.loadImages(mstart,mend); + } else{ + //停止任务 + mImageLoader.cancelAllTasks(); + } + } + + @Override + public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + //滑不滑动都会调用 + mstart = firstVisibleItem; + mend = firstVisibleItem + visibleItemCount; + //第一次显示调用 + if(mFirst == true && visibleItemCount > 0){ + mImageLoader.loadImages(mstart,mend); + mFirst = false; + } + } + class ViewHolder{ public TextView newTitle, newTime, newDesc, newContent; public ImageView newPic;