安卓。异步任务和用户界面

问题描述 投票:1回答:2

我使用的是Android Studio,但我有点卡住了。AsyncTask

我的应用程序是为了在RFID扫描仪上运行,其中一个功能是在一个充满标签的仓库中找到一个特定的标签。

因此,我需要能够在设备在仓库中移动时不断地扫描和读取标签,当发现一个匹配的标签时,设备会发出声音来提醒用户。我通过循环来实现这个功能,但问题是我需要允许用户在点击按钮时取消这个功能,这将建议把搜索标签的工作移到一个异步任务中。

我目前所做的是在onKeyDown事件中,启动读取tag的代码,并更新一个带有tagNumber的变量,然后在这个变量的变化监听器周围设置一个循环,以便在这个事件中提取tag号,如果结果不成功(没有匹配),则调用重新启动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方法,但是失败了,从我读到的内容来看,不可能在async taskmethod中访问UI项目。

我读到的其他方法是将它放在 AsyncTask 类,然后从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);
    }

反正我也找不到类似于.net中的IsInvokeRequired的函数。

有什么我还没有发现的解决方法吗? 我应该完全改变这个问题的方法吗?不知道如何才能让这个搜索继续运行,并监听Cancel点击事件来取消出这个搜索 "循环"

java android
2个回答
2
投票

有一天,我已经有了这个疑问,我没有找到一个解决方案(我快疯了),所以我找到了解决方案阅读 安卓开发者官方指南. 我注意到我做的事情和你的问题一样,我走错了路,因为任何在当前Activity上运行的循环都会阻止UI的交互。

解决办法。

解决这个问题的方法是创建至少两个可运行的类(扩展的Threads),在一个不同于当前Activity的新Thread中同时运行。

创建第一个可运行的类,只用于管理连接的生命周期,另一个用于在射频识别设备和智能手机之间交换信息。

我建议你学习这个简单的 蓝牙聊天的例子 也许你的问题会得到解答。


0
投票

我可以给你一个通用的答案,如何处理这个问题,因为我实现了类似的东西为射频识别设备。首先,我想你有一个蓝牙连接的东西一个长的线的 安卓开发者蓝牙指南. 如果你这样实现,你可以随时随地对socket进行读写。它不依赖于Activity,并与应用程序一起运行。

即使你的应用程序不使用蓝牙,它仍然可以使用相同的结构与一个 SocketThread 和a ConnectorThread. 为了通信目的,您可以使用 android.os.Handler 诸如此类 EventBus.

不要试图硬接任何 Activity 这样的。宁可让 Activity 落实 Interface 来控制设备之间的连接。

© www.soinside.com 2019 - 2024. All rights reserved.