0

我的程序在活动运行代码中的 While 循环中运行。它每 100 毫秒左右读取一次 USB 数据。当该 USB 数据流中的一个字节设置时,我称之为 startVoiceRecognitionActivity():

private void startVoiceRecognitionActivity() {
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
            RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Voice recognition Demo...");
        startActivityForResult(intent, REQUEST_CODE);       
}

语音识别器运行良好,我的 USB 数据流 While 循环在语音识别器执行操作时继续运行。

但是,在 onActivityResult 执行后,我的 While 循环被终止。我需要留在这个while循环中,我该怎么做?

编辑:我一直在调试它,并将显示相关的当前代码。似乎 onActivityReturn 在程序崩溃之前以某种方式破坏了 USB。我已经编辑了我的 while 循环,以显示我在语音识别器调用后如何尝试重新建立 USB。

使用显示的代码,在运行调试的语音识别器调用之后,代码在没有断点的情况下中断。如果我从那里恢复代码执行,程序就会停止,就像我单击了 Terminate 按钮一样。这是我的计算机屏幕,当执行本身发生中断时,它似乎是一个 NullPointerException 问题,仍然超出我的知识库。希望有人能指出我正确的方向。

我开始相信您在下图中看到的线程 [<12> Thread-130](正在运行)是罪魁祸首。此线程出现在从语音识别器调用返回时。我想我需要确保在语音识别器调用后执行返回到原始线程,但我可能会离开这里吗?

在此处输入图像描述

或者更好(也许),有没有办法在我调用语音识别器时杀死原始线程 <11>?

哇,就是这样,或者至少我是这么认为的,我需要做的就是打破;在我启动语音识别器后退出 while 循环(我还必须在 USB 请求失败时退出 while 循环)。

而且,我不必在 runOnUiThread() 中启动语音识别器。

我认为这很有魅力,但我注意到暂停的线程在累积,最终程序停止执行语音识别器。我相信我会追查到这一点,但任何智慧之言都会有所帮助。

抱歉这么多细节,但我会将整个初学者的思考过程留给后面的人(除非你开始对此投反对票)。

PS 这是多么棒的调试环境啊!!!!

似乎挂起的线程是在我调试时创建的,还没有弄清楚它为什么停止工作,但可能是所有那些挂起的线程。我会弄清楚的。我无法复制该问题,并且我认为我确实已经找到了答案(上图),但我会等一会儿再将其发布为答案,以确保。

1/21 11:14 EST:还有 2 个问题

- 大约十分之一的语音识别调用会导致执行 onResume(),但 run() 在 onResume() 之后不会执行(另外 9 次 run() 在 onResume() 之后输入)。这会导致我的程序挂起,因为没有进入 while 循环。

- 每次用户使用系统的“返回”箭头使用另一个程序然后返回到我的程序时,就会出现另一个线程(带有自己的 while 循环)。实际上,这会创建我的程序的多个实例,并且是不可接受的。

而且,我又回到了在 runOnUiThread() 中启动语音识别器,我认为挂断更少。

美国东部时间 1 月 21 日下午 1:27:

再一次,我想我已经成功了。我已经调用了 100 次语音识别,间歇性地使用了其他程序,并且在我的调试窗口中仍然有相同数量的运行线程并且它没有挂断。

我所做的是,声明一个活动级别整数 exitloopnow。我在 onCreate、onStart 和 onResume 中将 exitloopnow 设置为 0。我在 onPause、onStop 和 onDestroy 中将 exitloopnow 设置为 1。在 run() while 循环中,如果 exitloopnow==1 则中断。

同样,如果这继续有效,我会将其设置为答案,除非有人提出更好的答案。

美国东部时间 1 月 21 日下午 2:00:

我想100次是不够的。我在它挂起的地方以调试模式捕捉到它。它似乎卡在下图所示的 .resquestWait() 上。

我在“不可用 [本机方法]”上找不到太多内容,所以我又被卡住了。如果我恢复代码执行并再次中断,它总是在他的行 (350) 上。

美国东部时间 1 月 22 日上午 9:20:

虽然代码挂在第 350 行,但我可以拔下 USB 电缆,然后将其重新插入,这确实会创建另一个工作线程,但这是不可取的。我还可以使用 Android 的后退按钮并通过在最近的应用程序中选择程序来获取另一个线程,这也是不可取的。

在此处输入图像描述

这是 onActivityResult():

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if (requestCode == REQUEST_CODE && resultCode == RESULT_OK)
    {
        // Populate the wordsList with the String values the recognition engine thought it heard
        final ArrayList<String> matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

        this.runOnUiThread(new Runnable() {
            public void run() {
                ((TextView) findViewById(R.id.tvTitle)).setText(matches.get(0));
            }
        });
        BusyV=0;
    }
    super.onActivityResult(requestCode, resultCode, data);
}

而当前的 While 循环:

@Override
public void run() {
    while (true) {
        request.queue(buffer, 64);
        if (mConnection.requestWait() == request) {
            if (buffer.get(7)==0) {  //New Box (Yellow) button pressed now
                this.runOnUiThread(new Runnable() {
                    public void run() {
                        ((TextView) findViewById(R.id.tvSpine)).setText("Spine");
                        ((TextView) findViewById(R.id.tvPage)).setText("Page");
                        ((TextView) findViewById(R.id.tvThick)).setText("Thick");
                    }
                }); 
                if (CanRecog==1) {
                    if (BusyV!=1) {
                        BusyV=1;

                        this.runOnUiThread(new Runnable() {
                            public void run() {
                                Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
                                intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                                        RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
                                intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Voice recognition ...");
                                startActivityForResult(intent, REQUEST_CODE);       
                            }
                        });
                    }
                }
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
        } else {
            this.runOnUiThread(new Runnable() {
                public void run() {
                    ((TextView) findViewById(R.id.tvZnum)).setText("USB lost at "+ System.currentTimeMillis());
                    ((TextView) findViewById(R.id.tvXnum)).setText("   ");
                }
            });
        }
    }
}

以及我尝试重新建立 USB 的代码(在 onResume 代码中,因为在语音识别 onActivityResult() 之后会自动调用 onResume:

@Override
public void onResume() {
    super.onResume();
    Intent intent = getIntent();
    Log.d(TAG, "intent: " + intent);
    savetofile("1 intent: " + intent);
    connectToUsb();
}

private void connectToUsb() {
    if (amconnected==1) {
        mConnection.close(); 
        request.close(); 
    } else {            
        setupusb();
    }
    amconnected=0;
    while(amconnected==0) {
        doconnect();
    }   
    request.initialize(mConnection, mEndpointIntr);
}

private void setupusb() {
    mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
    mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
    IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
    registerReceiver(mUsbReceiver, filter);
}

private void doconnect() {
    HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
    Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
    while (deviceIterator.hasNext()) {
        UsbDevice device1 = deviceIterator.next();
        if (device1.getVendorId() == 1240 & device1.getProductId() == 63) {
            mUsbManager.requestPermission(device1, mPermissionIntent);
            setDevice(device1);
        }
    }
}

private void setDevice(UsbDevice device) {
    Log.d(TAG, "setDevice " + device);
    savetofile("2 setDevice " + device);
    if (device.getInterfaceCount() != 1) {
        Log.e(TAG, "could not find interface");
        savetofile("3 could not find interface");
        return;
    }
    UsbInterface intf = device.getInterface(0);
    UsbEndpoint ep = intf.getEndpoint(0);
    if (ep.getType() != UsbConstants.USB_ENDPOINT_XFER_INT) {
        Log.e(TAG, "endpoint is not interrupt type");
        savetofile("5 endpoint is not interrupt type");
        return;
    }
    mEndpointIntr = ep;
    if (device != null) {
        UsbDeviceConnection connection = mUsbManager.openDevice(device);
        if (connection != null && connection.claimInterface(intf, true)) {
            Log.d(TAG, "open SUCCESS");
            savetofile("6 open SUCCESS");
            mConnection = connection;
            Thread thread = new Thread(this);
            thread.start();
            amconnected=1;
        } else {
            Log.d(TAG, "open FAIL");
            savetofile("7 open FAIL");
            mConnection = null;
        }
    }
}

和我的清单:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="act.ProMeasure2D">

<uses-feature android:name="android.hardware.usb.host" />
<uses-sdk android:minSdkVersion="13" />

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />

<application android:theme="@android:style/Theme.Black" android:label="ProMeasure2D">
    <activity android:name="act.ProMeasure2D.ProMeasure2DActivity"
        android:label="ProMeasure2D">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <intent-filter>
            <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
        </intent-filter>

        <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
            android:resource="@xml/device_filter" />
    </activity>
</application>

和我的项目结构: 在此处输入图像描述

4

1 回答 1

0

就是这样,我需要做的就是打破;在我启动语音识别器后退出 while 循环(我还必须在 USB 请求失败时退出 while 循环)。

而且,我不必在 runOnUiThread() 中启动语音识别器。

现在就像一个魅力。

抱歉这么多细节,但我会将整个初学者的思考过程留给后面的人(除非你开始对此投反对票)。

PS 这是多么棒的调试环境啊!!!!

于 2013-01-21T02:19:09.620 回答