Android:异步任务和用户界面

时间:2018-01-24 12:18:25

标签: java android

我使用的是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;

2 个答案:

答案 0 :(得分:1)

有一天我已经有了这个疑问,我没有找到解决方案(我疯了),所以我找到了解决方案android developer official guide。我注意到我做了类似你问题的事情而且我走错了路,因为当前Activity上的任何循环运行都会阻止UI的交互。

<强>解决方案:

此问题的解决方案是创建至少两个可运行的类(扩展线程),以便在与当前活动不同的新线程中运行。

创建第一个runnable类,仅用于管理连接的生命周期,另一个用于在rfid设备和智能手机之间交换消息。

我建议你学习这个简单的BluetoothChat example,也许你会回答你的问题。

我希望这些技巧可以帮到你!

此致 Renan Schroeder

答案 1 :(得分:0)

自从我为rfid设备实现了类似的功能后,我可以给你一个关于如何处理这个问题的通用答案。首先,我想你的蓝牙连接与android developer bluetooth guide的行很长。如果你像那样实现它,你可以随时随地读/写插槽。它不依赖于活动,并与应用程序一起运行。

即使您的应用程序不使用蓝牙,它仍然可以使用与SocketThreadConnectorThread相同的结构。出于沟通目的,您可以使用android.os.Handler或类似EventBus的内容。

不要试图像这样强硬任何Activity。而是让Activity实现Interface来控制/监听设备之间的连接。