我使用的是Android Studio,我对AsyncTask
我的应用程序旨在在RFID扫描仪上运行,其中一项功能是在一个装满标记物品的仓库中找到一个特定标签。
因此,当设备在仓库中移动时,我需要能够连续扫描和读取标签,并且当找到匹配时,设备发出声音以提醒用户。我得到这个用循环,但问题是我需要允许用户通过点击按钮取消此操作,这将建议将标签的搜索移动到异步任务。
我目前正在做的是onKeyDown事件,触发执行标记读取的代码并使用tagNumber更新变量,然后在此变量的更改侦听器周围放置一个循环来拉取此标记号event,如果结果不成功(不匹配),则重新激活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);
}
我想从async类中的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中使用的那样,我无论如何都能找到......
有没有一种解决方法我还没有偶然发现?我应该完全改变这个问题的方法吗?不确定如何保持此搜索运行并收听取消点击事件以取消此搜索&#34;循环&#34;
答案 0 :(得分:1)
有一天我已经有了这个疑问,我没有找到解决方案(我疯了),所以我找到了解决方案android developer official guide。我注意到我做了类似你问题的事情而且我走错了路,因为当前Activity上的任何循环运行都会阻止UI的交互。
<强>解决方案:强>
此问题的解决方案是创建至少两个可运行的类(扩展线程),以便在与当前活动不同的新线程中运行。
创建第一个runnable类,仅用于管理连接的生命周期,另一个用于在rfid设备和智能手机之间交换消息。
我建议你学习这个简单的BluetoothChat example,也许你会回答你的问题。
我希望这些技巧可以帮到你!
此致 Renan Schroeder
答案 1 :(得分:0)
自从我为rfid设备实现了类似的功能后,我可以给你一个关于如何处理这个问题的通用答案。首先,我想你的蓝牙连接与android developer bluetooth guide的行很长。如果你像那样实现它,你可以随时随地读/写插槽。它不依赖于活动,并与应用程序一起运行。
即使您的应用程序不使用蓝牙,它仍然可以使用与SocketThread
和ConnectorThread
相同的结构。出于沟通目的,您可以使用android.os.Handler
或类似EventBus的内容。
不要试图像这样强硬任何Activity
。而是让Activity
实现Interface
来控制/监听设备之间的连接。