【Android-java】循环中进行定时运行任务的-每300ms跑一次任务;如何在循环(读取数据)中进行延迟任务操作思路分析

需求(问题)

后台交互限制在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);

    }

这回就不会跟后台过多交互了,起到缓冲保护作用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值