如何使用服务和 ASyncTask 轮询服务器并更新 UI



我目前正在使用ZXing条形码阅读器扫描QR码。使用该API,ZXing代码具有"onActivityResult()"方法来处理成功或失败扫描。

如果成功,我调用 checkQR 类,它由 ASyncTask 组成。目前它返回结果一次,因为它仅在扫描后调用。

如何以 30 秒的间隔继续调用/轮询,更新 textView 并在检测到特定文本后停止它(终止服务)(例如"已完成")?

注意:CheckQR 构造函数采用上下文和文本视图。orderstatus 是我希望更新来自服务器的响应的文本视图。

onActivityResult() 的部分代码

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
    if (scanResult != null) {
        String contents = scanResult.getContents();
        if (contents != null) {             
            orderNum.setText("Order Number: " + contents);
            new CheckQR(this,orderStatus).execute(contents);
        } else {
        //failed
        }
    }

你的问题有太多的警告。是否希望此调度程序在活动之外继续运行?您是否想每 30 秒严格调用一次 CheckQR,即使前一个还没有完成?

我假设您想调用 CheckQR 只要您的活动仍然存在,因为它会更新TextView。因此,如果您想进行在 CheckQR 完成后开始的链调用,那么您只需在 onPostExexute 中使用 Handler 递归地执行此操作。

private CheckQR cqr;
class CheckQR extends AsyncTask<Void, Void, String>{
    @Override
    protected String doInBackground(Void... voids) {
        if (isCancelled()){
            return null;
        }
        String res = httpCall();
        return res;
    }
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        if (result == null || isCancelled() || result.equals("it is done")){
            return;
        }
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                cqr = new CheckQR();
                cqr.execute();
            }
        }, 30000);
    }
}
@Override
protected void onDestroy() {
    super.onDestroy();
    cqr.cancel(true);
}

如果您想每 30 秒启动一次 CheckQR,无论前一个是否完成

,请使用ScheduledExecutorService
        ScheduledExecutorService scheduler =
            Executors.newSingleThreadScheduledExecutor();
        ScheduledFuture scheduledFuture = scheduler.scheduleAtFixedRate
            (new Thread(){
                @Override
                public void run() {
                    //do blocking http call
                    if(stopCondition)//when stop condition is met
                        scheduledFuture.cancel(false);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (!flagActivityOnDestroyedRaised){
                                // you need this flag to prevent 
                                // updating UI when Activity is already 
                                // destroyed
                                textView.setText("aaaa");
                            }
                        }
                    });
                }
            }, 0, 30, TimeUnit.SECONDS);

在销毁中清理

@Override
protected void onDestroy() {
    super.onDestroy();
    scheduledFuture.cancel(false);
    flagActivityOnDestroyedRaised = true; 
}

此代码只是一个伪代码。您需要将此处的一些引用声明为实例变量并使用正确的方法。如果您使用ScheduledExecutorService那么您需要使用 runOnUiThread 将 AsyncTask 解包到 Thread 中。

相关内容

  • 没有找到相关文章

最新更新