This is the 15th day of my participation in the First Challenge 2022
Album Photo show
In ListView, the asynchronous batch image loading service uses the mechanism of round-the-clock task queue to complete the service
Modify interface to pass a parameter type, query general information, modify UrlFactory
public class UrlFactory {
/** * url **@param keyword
* @return json
*/
public static String getNewMusicListUrl(String keyword) {
String url = "Https://v2.alapi.cn/api/music/search?token= registered users center view token&keyword =" + keyword+"&type=1018";
returnurl; }}Copy the code
View the returned JSON dataSince the return structure has changed, the corresponding entity class
public class MusicDataModel {
public MusicSongModel song;
}
public class MusicSongModel {
public List<MusicItem> songs;
}
public class MusicItem {
public String id;
public String name;
public String albumName;
public String albumPic;
public AlbumModel al;
}
public class AlbumModel {
public String name;
public String picUrl;
}
Copy the code
Modify JsonParser
public class JsonParser {
/** * Parses the XML content through the input stream using XMLPULL parsing **@param is
* @return List<Music>
*/
public static List<MusicItem> parseMusicList(InputStream is) throws IOException, JSONException {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = "";
while((line = reader.readLine()) ! =null) {
sb.append(line);
}
String json = sb.toString();
JSONObject obj = new JSONObject(json);
JSONObject data = obj.getJSONObject("data");
JSONObject song = data.getJSONObject("song");
JSONArray songs = song.getJSONArray("songs");
List<MusicItem> list = new ArrayList<>();
for (int i = 0; i < songs.length(); i++) {
JSONObject s = songs.getJSONObject(i);
String id = s.getString("id");
String name = s.getString("name");
MusicItem musicItem = new MusicItem();
musicItem.id = id;
musicItem.name = name;
musicItem.albumName = s.getJSONObject("al").getString("name");
musicItem.albumPic = s.getJSONObject("al").getString("picUrl");
list.add(musicItem);
}
returnlist; }}Copy the code
Modify MusicAdapter
public class MusicAdapter extends BaseAdapter {
private Context context;
private List<MusicItem> musics;
private LayoutInflater inflater;
private List<ImageLoaderTask> tasks = new ArrayList<ImageLoaderTask>();
private Thread workThread;
private boolean isLoop = true;
private ListView listView;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case HANDLER_IMAGE_LOAD_SUCCESS:
// Set the bitmap for the corresponding Imageview
ImageLoaderTask task = (ImageLoaderTask) msg.obj;
Bitmap bitmap = task.bitmap;
ImageView imageView = (ImageView) listView.findViewWithTag(task.path);
if(imageView ! =null) {
if(bitmap ! =null) {
imageView.setImageBitmap(bitmap);
} else{ imageView.setImageResource(R.mipmap.ic_launcher); }}break; }}};public static final int HANDLER_IMAGE_LOAD_SUCCESS = 1;
public MusicAdapter(Context context, List<MusicItem> musics, ListView listView) {
super(context, musics);
this.context = context;
this.musics = musics;
this.inflater = LayoutInflater.from(context);
this.listView = listView;
// Start the worker thread to cycle through the task set
workThread = new Thread() {
@Override
public void run(a) {
while (isLoop) {
if(! tasks.isEmpty()) {// Not an empty set
ImageLoaderTask task = tasks.remove(0);//remove returns the data at the same time
String url = task.path;
// Send an HTTP request to download the image
Bitmap bitmap = loadBitmap(url);
task.bitmap = bitmap;
// Update the interface and send a message to Handler
Message message = new Message();
message.what = HANDLER_IMAGE_LOAD_SUCCESS;
message.obj = task;
handler.sendMessage(message);
} else {// Empty set wait
try {
/ / lock
synchronized(workThread) { workThread.wait(); }}catch(InterruptedException e) { e.printStackTrace(); }}}}}; workThread.start(); }/** ** Send an HTTP request to the url **@param url
* @return* /
private Bitmap loadBitmap(String url) {
try {
InputStream is = HttpUtils.getInputStream(url);
Bitmap bitmap = BitmapFactory.decodeStream(is);
return bitmap;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
public int getCount(a) {
return musics.size();
}
@Override
public MusicItem getItem(int i) {
return musics.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder = null;
if (view == null) {
view = inflater.inflate(R.layout.item_lv_music, null);
holder = new ViewHolder();
holder.imgPic = view.findViewById(R.id.img_Pic);
holder.tvName = view.findViewById(R.id.tv_name);
holder.tvAlbum = view.findViewById(R.id.tv_album);
view.setTag(holder);
}
holder = (ViewHolder) view.getTag();
// Assign a value to the control
MusicItem music = getItem(i);
holder.tvName.setText(music.name);
holder.tvAlbum.setText(music.albumName);
// The image is on the server. It should be displayed from the thread, but this is adapter.getView()
// The phone will explode if I start the thread every time a picture is displayed.
// Set the image to holder.imgpic
// Download the task to an image in the task collection
holder.imgPic.setTag(music.albumPic);
ImageLoaderTask task = new ImageLoaderTask();
task.path = music.albumPic;
tasks.add(task);
// Wake up the worker thread
synchronized (workThread) {
workThread.notify();
}
return view;
}
class ViewHolder {
ImageView imgPic;
TextView tvName;
TextView tvAlbum;
}
class ImageLoaderTask {
String path;// Save the image download path
Bitmap bitmap;// Download the image successfully}}Copy the code
NewMusicListFrament is modified as follows
public void setAdapter(List<MusicItem> musics) {
adapter = new MusicAdapter(getActivity(), musics, listView);
listView.setAdapter(adapter);
}
Copy the code
To run the program
Image compression
Common image formats: JPG: the most commonly used compression format with a high compression ratio, but does not support transparent colors. PNG: Supports transparent colors. GIF: supports dynamic images
Provides a utility class for compressing bitmap BitmapUtils
public class BitmapUtils {
/** * Compress the image to get the corresponding size of the image **@paramIs Input stream *@paramWidth Target width *@paramHeight Target height *@return* /
public static Bitmap loadBitmap(InputStream is, int width, int height) throws IOException {
// parse is to read data into byte[]
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// Read data from the input stream into bos
byte[] buffer = new byte[1024 * 8];
int length = 0;
while((length = is.read(buffer)) ! = -1) {
bos.write(buffer, 0, length);
bos.flush();
}
// This byte array describes the complete information of an image
byte[] bytes = bos.toByteArray();
// Get the original size of the image
BitmapFactory.Options options = new BitmapFactory.Options();
// Only boundary attributes are loaded
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
// Calculate the compression ratio according to the original size and width and height
int w = options.outWidth / width;
int h = options.outHeight / height;
int scale = w > h ? w : h;
// Perform compression
options.inJustDecodeBounds = false;
options.inSampleSize = scale;// Set the zoom scale
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
returnbitmap; }}Copy the code
use
Bitmap bitmap = BitmapUtils.loadBitmap(is,5.5);
Copy the code
Apply to the previous project and modify the MusicAdapter loadBitmap method
private Bitmap loadBitmap(String url) {
try {
InputStream is = HttpUtils.getInputStream(url);
Bitmap bitmap = BitmapUtils.loadBitmap(is,100.100);
//Bitmap bitmap = BitmapFactory.decodeStream(is);
return bitmap;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Copy the code