如何使用 Service 和 ASyncTask 轮询服务器并更新 UI
How to poll server using Service and ASyncTask and update UI
我目前正在使用 ZXing Barcode reader 扫描二维码。使用 API,ZXing 代码有一个 "onActivityResult()" 方法来处理成功或失败扫描。
如果成功,我会调用由 ASyncTask 组成的 checkQR class。目前它returns一次结果,因为它只在扫描后调用。
如何让calling/polling每隔30秒更新textView并在检测到某个文本(例如"it is done")后停止它(杀死服务)?
注意:CheckQR 构造函数接受 Context 和 TextView。
orderstatus 是我希望更新来自服务器的响应的 TextView。
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
}
}
你的问题有太多的注意事项。
您希望此调度程序将 运行 保持在 Activity 之外吗?
你想死板地每 30 秒调用一次 CheckQR,即使前一个还没有完成吗?
我假设您想在 Activity 存活期间一直调用 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);
在 onDestroy 中清理
@Override
protected void onDestroy() {
super.onDestroy();
scheduledFuture.cancel(false);
flagActivityOnDestroyedRaised = true;
}
这段代码只是一个伪代码。您需要将此处的一些引用声明为实例变量并使用正确的方法。如果您使用 ScheduledExecutorService
那么您需要使用 runOnUiThread
.
将 AsyncTask 解包到 Thread
我目前正在使用 ZXing Barcode reader 扫描二维码。使用 API,ZXing 代码有一个 "onActivityResult()" 方法来处理成功或失败扫描。
如果成功,我会调用由 ASyncTask 组成的 checkQR class。目前它returns一次结果,因为它只在扫描后调用。
如何让calling/polling每隔30秒更新textView并在检测到某个文本(例如"it is done")后停止它(杀死服务)?
注意:CheckQR 构造函数接受 Context 和 TextView。 orderstatus 是我希望更新来自服务器的响应的 TextView。
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
}
}
你的问题有太多的注意事项。 您希望此调度程序将 运行 保持在 Activity 之外吗? 你想死板地每 30 秒调用一次 CheckQR,即使前一个还没有完成吗?
我假设您想在 Activity 存活期间一直调用 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);
在 onDestroy 中清理
@Override
protected void onDestroy() {
super.onDestroy();
scheduledFuture.cancel(false);
flagActivityOnDestroyedRaised = true;
}
这段代码只是一个伪代码。您需要将此处的一些引用声明为实例变量并使用正确的方法。如果您使用 ScheduledExecutorService
那么您需要使用 runOnUiThread
.
Thread