[英]Android: Async Tasks and UI
我正在使用 Android Studio,但在AsyncTask
上有点卡住了
我的应用程序旨在在 RFID 扫描仪上运行,其中一项功能是在装满标记物品的仓库中找到一个特定标签。
因此,当设备在仓库中移动时,我需要能够连续扫描和读取标签,当找到匹配项时,设备会发出声音提醒用户。 我让它与循环一起工作,但问题是我需要允许用户通过单击按钮取消此操作,这会建议将标签搜索移动到异步任务。
我目前正在做的是在 onKeyDown 事件中,触发读取标签并使用 tagNumber 更新变量的代码,然后在此变量的更改侦听器周围放置一个循环以提取此事件上的标签号,如果结果是不成功(不匹配)调用重新触发 keydown 事件并重复该过程直到找到匹配项。
public boolean onKeyDown(int keyCode, KeyEvent event) {
while (Scan.equals("true")) {
try {
// ReadAction.onStart();
if ((keyCode == KeyEvent.KEYCODE_SOFT_RIGHT || keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT
|| keyCode == KeyEvent.KEYCODE_SHIFT_LEFT
|| keyCode == KeyEvent.KEYCODE_F7 || keyCode == KeyEvent.KEYCODE_F8) && event.getRepeatCount() <= 0
&& ReadAction.mReader.getAction() == ActionState.Stop && ReadAction.mReader.getState() == ConnectionState.Connected) {
ATLog.i(TAG, "INFO. onKeyDown(%d, %d)", keyCode, event.getAction());
mElapsedTick = SystemClock.elapsedRealtime() - mTick;
if (mTick == 0 || mElapsedTick > SKIP_KEY_EVENT_TIME) {
startAction();
mTick = SystemClock.elapsedRealtime();
} else {
ATLog.e(TAG, "INFO. Skip key down event(elapsed:" + mElapsedTick + ")");
return super.onKeyDown(keyCode, event);
}
final String SearchedTagNo = getScannedTag();
ReadAction.setListener(new BaseReadAction.ChangeListener() {
@Override
public void onChange() {
if (Scan.equals("true")) {
String scannedTag= ReadAction.getEpcNo();
if (!SearchedTagNo .equals(scannedTag)) {
onKeyDown(2, keyEvent);
} else if (SearchedTagEPC.equals(EPCTag)) {
//indicate success to user on screen and by sound
mSound.playSuccess();
txtSearchResult.setText(" Found in this Area");
}
}
}
});
return true;
}
} catch (Exception e) {
logWork.AppendLog("ERROR: " + e.getMessage() + " m_KeyDown(), a_AssignTag");
Toast.makeText(Search_Activity.this, e.getMessage().toString(),
Toast.LENGTH_LONG).show();
}
}
return super.onKeyDown(keyCode, event);
}
我想从异步类中的 doInBackground 方法调用这个 onKeyDown 方法/事件,但它失败了,并且从我读到的内容来看,无法访问异步任务/方法中的 UI 项目
我读过的替代方法是将它放在AsyncTask
类的 onProgressUpdate 方法中,并从 doInBackground 调用发布进度,但这对我也不起作用。
class AsyncSearch extends AsyncTask <Void, Void, Void> {
KeyEvent keyEvent;
Search_Activity searchActivity = new Search_Activity(); //thinking this is causing the problem
public AsyncSearch() {
keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, 2);
}
@Override
protected Void doInBackground(Void... params) {
try {
//calling onProgressUpdate to fire, and placing code that needs access to UI thread in the onProgressUpdate method
//because you cannot instantiate a class in a background worker.
publishProgress();
} catch (Exception e) {
throw e;
}
return null;
}
@Override
protected void onProgressUpdate(Void... values) {
//calls the onKeyDown event in Search_Activity Asynchornously
searchActivity.onKeyDown(2, keyEvent);
}
IsInvokeRequired 没有类似在 .net 中使用的等效项,无论如何我都可以找到...
是否有我尚未偶然发现的解决方法? 我应该完全改变解决这个问题的方法吗? 不知道如何保持此搜索运行并收听 Cancel click 事件以取消此搜索“循环”
有一天我已经有了这个疑问,但我没有找到解决方案(我快疯了),所以我找到了阅读android developer official guide的解决方案。 我注意到我正在做类似于你的问题的事情,而且我走错了路,导致当前活动上运行的任何循环都将始终阻止 UI 交互。
解决方法:
这个问题的解决方案是创建至少两个可运行的类(扩展线程),它们都可以在与当前活动不同的新线程中运行。
创建第一个可运行类仅用于管理连接的生命周期,另一个用于在 rfid 设备和智能手机之间交换消息。
我建议您学习这个简单的BluetoothChat 示例,也许您的问题会得到解答。
因为我为 rfid 设备实现了类似的东西,所以我可以就如何解决这个问题给你一个通用的答案。 首先,我假设您有一个蓝牙连接, 就像 android 开发人员蓝牙指南中的内容一样。 如果您像这样实现它,您可以随时随地读取/写入套接字。 它不依赖于 Activity 并与应用程序一起运行。
即使您的应用程序不使用蓝牙,它仍然可以使用具有SocketThread
和ConnectorThread
的相同结构。 出于通信目的,您可以使用android.os.Handler
或EventBus 之类的东西。
不要试图硬连线任何这样的Activity
。 而是让Activity
实现一个Interface
来控制/监听设备之间的连接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.