需求(问题)
后台交互限制在QPS为每秒40次的调用,但是我这边有5000个数据需要交互。最开始的想法很简单就是延迟运行即可:
在for循环中进行延迟后台交互即可!
private HashMap<String, ClipObj> getSongsMap(ArrayList<String> songIDs) {
HashMap<String , ClipObj> map = new HashMap();
songsFiveThousandInfoResourceLoadListener.onStart();//正式开始
//开始循环获取音乐信息
for(String songID : songIDs){
//主线程跑!
Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
@Override
public void run() {
ArrayList<String> songIDLists = new ArrayList<>();
songIDLists.add(songID);
String params = new JsonBuilder()
.addParams("songs_id",songIDLists)
.build();
//获取歌曲信息
mCopyrightedMusic.sendExtendedRequest(COMMAND, params, new IZegoCopyrightedMusicSendExtendedRequestCallback() {
@Override
public void onSendExtendedRequestCallback(int errorCode, String command, String result) {
if(errorCode == 0){
try {
JSONObject jsonObject = new JSONObject(result);
final JSONObject data = jsonObject.getJSONObject("data");
final JSONArray songs = data.getJSONArray("songs");//是数组哦!
songsDTO= new Gson().fromJson(songs.get(0).toString(),SongsDTO.class);
requestConfig.songID = songID;//音乐id
requestConfig.mode = ZegoCopyrightedMusicBillingMode.COUNT;
//获取音乐高潮资源
Log.d("Test","test");
mCopyrightedMusic.requestAccompanimentClip(requestConfig, new IZegoCopyrightedMusicRequestAccompanimentClipCallback() {
@Override
public void onRequestAccompanimentClipCallback(int errorCode, String resource) {
Log.d(TAG, "onRequestAccompanimentClipCallback:"+errorCode);
if(errorCode == 0){
Log.d(TAG, resource);
clip = ClipObj.objectFromData(resource);
songsMap.put(clip.getData().getSongId(), clip);
songsFiveThousandInfoResourceLoadListener.onProgress((songIDs.indexOf(songID)+1));// 计算下载频率
if(songID.equals(songIDs.get(songIDs.size()-1))){
songsFiveThousandInfoResourceLoadListener.onSuccess();
}
}else{
Toast.makeText(getApplicationContext(),"ID:"+clip.getData().getSongId()+"获取歌曲信息失败:"+errorCode,Toast.LENGTH_SHORT).show();
}
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}else{
songsFiveThousandInfoResourceLoadListener.onFailure(errorCode);
}
}
});
}
},300);
}
return map;
}
日志显示时间差根本不是300ms:
在handler中延迟300ms,只是将这一串任务滞后300ms触发的。for是连续的,这就只是相当于整个for是向后延迟300ms罢了
解决方法
- 听大神说,可以采用定时器的方式和后台交互。300ms后跑一次。
检索到相关的参考资料:
Java并发编程:ScheduledExecutorService执行周期任务
实际上我还是想复杂了,老想在循环中for解决,实际上通过一个计数器进行延迟触发即可:
伪代码:
定时任务:
int position = -1;
new Runnable() {
@Override
public void run() {
if(position >= 最大任务数,数组长度){
return;
}
position ++;
//伪代码获取数组position位置的数据进行执行
}
}
最终修改后的代码:
private void getSongsMap(ArrayList<String> songIDs) {
songsFiveThousandInfoResourceLoadListener.onStart();//正式开始
TimerTask task = new TimerTask() {
@Override
public void run() {
position++;
if(position >= songIDs.size()){
return ;
}
//伪代码获取数组position位置的数据进行执行
ArrayList<String> songIDLists = new ArrayList<>();
songIDLists.add(songIDs.get(position));
String params = new JsonBuilder()
.addParams("songs_id",songIDLists)
.build();
//获取歌曲信息
mCopyrightedMusic.sendExtendedRequest(COMMAND, params, new IZegoCopyrightedMusicSendExtendedRequestCallback() {
@Override
public void onSendExtendedRequestCallback(int errorCode, String command, String result) {
if(errorCode == 0){
try {
JSONObject jsonObject = new JSONObject(result);
final JSONObject data = jsonObject.getJSONObject("data");
final JSONArray songs = data.getJSONArray("songs");//是数组哦!
songsDTO= new Gson().fromJson(songs.get(0).toString(),SongsDTO.class);
requestConfig.songID = songsDTO.getSongId();//音乐id
requestConfig.mode = ZegoCopyrightedMusicBillingMode.COUNT;//todo 切换成user就会返回参数错误的bug
//获取音乐高潮资源
Log.d("Test","test");
mCopyrightedMusic.requestAccompanimentClip(requestConfig, new IZegoCopyrightedMusicRequestAccompanimentClipCallback() {
@Override
public void onRequestAccompanimentClipCallback(int errorCode, String resource) {
Log.d(TAG, "onRequestAccompanimentClipCallback:"+errorCode);
if(errorCode == 0){
Log.d(TAG, resource);
clip = ClipObj.objectFromData(resource);
songsMap.put(clip.getData().getSongId(), clip);
songsFiveThousandInfoResourceLoadListener.onProgress(position);// 计算下载频率
if(position == songIDs.size()-1){
songsFiveThousandInfoResourceLoadListener.onSuccess();
return;
}
}else{
Toast.makeText(getApplicationContext(),"ID:"+clip.getData().getSongId()+"获取歌曲信息失败:"+errorCode+",现没获取到信息的数目为"+(++songsUNGivenInfoNum),Toast.LENGTH_SHORT).show();
}
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}else{
songsFiveThousandInfoResourceLoadListener.onFailure(errorCode);
}
}
});
}
};
Timer timer = new Timer();
// 定义开始等待时间 --- 等待 5 秒
// 1000ms = 1s
long delay = 150;
// 定义每次执行的间隔时间
long intevalPeriod = 300;
// schedules the task to be run in an interval
// 安排任务在一段时间内运行
timer.scheduleAtFixedRate(task, delay, intevalPeriod);
}
这回就不会跟后台过多交互了,起到缓冲保护作用。