当在其中添加一些 post 处理代码时,重载的 dispatchKeyEvent 方法会冻结应用程序
overloaded dispatchKeyEvent method freezes app when adding some post-processing code inside it
我目前正在开发一款使用条形码扫描仪扫描某些条形码的应用程序。因此,我通过重载 dispatchKeyEvent 方法来捕获数据。一切正常,只要我不尝试 post- 处理提示的条形码。
例如,此代码片段按预期工作。
private var promptedEAN:String = ""
override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
if(event?.action == KeyEvent.ACTION_DOWN) {
val pressedKey: Char = event.getUnicodeChar().toChar()
promptedEAN += pressedKey
val eTMengeKomm = findViewById<EditText>(R.id.eTMengeKomm)
eTMengeKomm.setText(promptedEAN, TextView.BufferType.EDITABLE)
val etCharge = findViewById<EditText>(R.id.eTCharge)
etCharge.setText(promptedEAN, TextView.BufferType.EDITABLE)
val etMHD = findViewById<EditText>(R.id.eTMHD)
etMHD.setText(promptedEAN, TextView.BufferType.EDITABLE)
}
return super.dispatchKeyEvent(event)
}
BUT,只要我想post-处理dispatchKeyEvent方法里面提示的条码,整个应用 冻结 。在这种情况下,我必须转到“设置”->“应用程序”->“强制停止”来终止我的应用程序,因为 none 个按钮都可以工作。
我的 post- 处理代码没有任何问题 - 我在 activity 的 onCreate 方法中使用测试字符串对其进行了测试。
我的问题是 为什么 我使用 dispatchKeyEvent 方法会出现这种行为?
这是我的代码。我在 OnCreate 方法中用键值对填充 HashMap,该方法在触发 dispatchKeyEvent.
之前开始
private var promptedEAN:String = ""
private var testPromptedEAN:String = "" //"C1020761303792692720001520060037009892547017L4"
private val hashMap : HashMap<String, Int> = HashMap()
override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
if(event?.action == KeyEvent.ACTION_DOWN) {
val pressedKey: Char = event.getUnicodeChar().toChar()
promptedEAN += pressedKey
testPromptedEAN = promptedEAN
val eTMengeKomm = findViewById<EditText>(R.id.eTMengeKomm)
eTMengeKomm.setText(promptedEAN, TextView.BufferType.EDITABLE)
val etCharge = findViewById<EditText>(R.id.eTCharge)
etCharge.setText(promptedEAN, TextView.BufferType.EDITABLE)
val etMHD = findViewById<EditText>(R.id.eTMHD)
etMHD.setText(promptedEAN, TextView.BufferType.EDITABLE)
if (testPromptedEAN.contains("C1",true) or testPromptedEAN.contains("C0",true)) { // EAN-128 Code
var pos:Int = 2 // init pos
var tail:String = testPromptedEAN.substring(pos) // init tail
var lookInString:String =""
while (pos<testPromptedEAN.length-1) {
var searchString:String = testPromptedEAN.substring(pos, pos+2) // look into 2-digit codes first
if (hashMap.containsKey(searchString)){
var lengthData4code:Int = hashMap.getValue(searchString) // get length of data for code from hash table
if (tail.length<lengthData4code){
lengthData4code = tail.length
lookInString = tail.substring(searchString.length, lengthData4code)
} else {
lookInString = tail.substring(searchString.length, searchString.length+lengthData4code) // data (part)string
}
if (lookInString.indexOf("$")>=0) { // string size is actually shorter than expected
lookInString = tail.substring(searchString.length,searchString.length+lookInString.indexOf("$"))
pos += (searchString.length + lookInString.length + 1)
} else {
pos += (searchString.length+ lengthData4code)
}
if (pos>=testPromptedEAN.length-1) {tail = ""}
else {tail = testPromptedEAN.substring(pos)}
if (searchString.contains("37", false)) {
//val eTMengeKomm = findViewById<EditText>(R.id.eTMengeKomm)
eTMengeKomm.setText(lookInString, TextView.BufferType.EDITABLE)
}
if (searchString.contains("10", false)) {
//val etCharge = findViewById<EditText>(R.id.eTCharge)
etCharge.setText(lookInString, TextView.BufferType.EDITABLE)
}
if (searchString.contains("15", false)) {
//val etMHD = findViewById<EditText>(R.id.eTMHD)
etMHD.setText(lookInString, TextView.BufferType.EDITABLE)
}
}
}
}
}
return super.dispatchKeyEvent(event)
}
非常感谢任何帮助。
我是如何解决这个问题的:
首先,我摆脱了重载的 dispachKeyEvent
方法。这在我的应用程序中造成了很多混乱,就我而言,后退和中间按钮根本没有反应。条形码 USB 扫描仪在 Android 中应该主要被识别为外部键盘,因此不需要此方法来将条形码捕获到特定的 EditText
字段中。之后,我将焦点设置在第一个 EditText
字段并在那里提示条形码。
其次,我了解到 while
循环 在活动的 UI 线程中不起作用 - 这就是原因,为什么我的应用程序一直在冻结。这就是为什么我在 Activity 中将 AsyncTask
实现为内部 class,并将所有后台处理逻辑放入 AsyncTask
的重载 doInBackround
方法中。在 onPostExecute
方法中,我为我的 EditText
字段设置了所有需要的值。
更新:我已经将整个后台逻辑提升到 ViewModel
中并最终摆脱了 AsyncTask
。
我目前正在开发一款使用条形码扫描仪扫描某些条形码的应用程序。因此,我通过重载 dispatchKeyEvent 方法来捕获数据。一切正常,只要我不尝试 post- 处理提示的条形码。
例如,此代码片段按预期工作。
private var promptedEAN:String = ""
override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
if(event?.action == KeyEvent.ACTION_DOWN) {
val pressedKey: Char = event.getUnicodeChar().toChar()
promptedEAN += pressedKey
val eTMengeKomm = findViewById<EditText>(R.id.eTMengeKomm)
eTMengeKomm.setText(promptedEAN, TextView.BufferType.EDITABLE)
val etCharge = findViewById<EditText>(R.id.eTCharge)
etCharge.setText(promptedEAN, TextView.BufferType.EDITABLE)
val etMHD = findViewById<EditText>(R.id.eTMHD)
etMHD.setText(promptedEAN, TextView.BufferType.EDITABLE)
}
return super.dispatchKeyEvent(event)
}
BUT,只要我想post-处理dispatchKeyEvent方法里面提示的条码,整个应用 冻结 。在这种情况下,我必须转到“设置”->“应用程序”->“强制停止”来终止我的应用程序,因为 none 个按钮都可以工作。
我的 post- 处理代码没有任何问题 - 我在 activity 的 onCreate 方法中使用测试字符串对其进行了测试。
我的问题是 为什么 我使用 dispatchKeyEvent 方法会出现这种行为?
这是我的代码。我在 OnCreate 方法中用键值对填充 HashMap,该方法在触发 dispatchKeyEvent.
之前开始 private var promptedEAN:String = ""
private var testPromptedEAN:String = "" //"C1020761303792692720001520060037009892547017L4"
private val hashMap : HashMap<String, Int> = HashMap()
override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
if(event?.action == KeyEvent.ACTION_DOWN) {
val pressedKey: Char = event.getUnicodeChar().toChar()
promptedEAN += pressedKey
testPromptedEAN = promptedEAN
val eTMengeKomm = findViewById<EditText>(R.id.eTMengeKomm)
eTMengeKomm.setText(promptedEAN, TextView.BufferType.EDITABLE)
val etCharge = findViewById<EditText>(R.id.eTCharge)
etCharge.setText(promptedEAN, TextView.BufferType.EDITABLE)
val etMHD = findViewById<EditText>(R.id.eTMHD)
etMHD.setText(promptedEAN, TextView.BufferType.EDITABLE)
if (testPromptedEAN.contains("C1",true) or testPromptedEAN.contains("C0",true)) { // EAN-128 Code
var pos:Int = 2 // init pos
var tail:String = testPromptedEAN.substring(pos) // init tail
var lookInString:String =""
while (pos<testPromptedEAN.length-1) {
var searchString:String = testPromptedEAN.substring(pos, pos+2) // look into 2-digit codes first
if (hashMap.containsKey(searchString)){
var lengthData4code:Int = hashMap.getValue(searchString) // get length of data for code from hash table
if (tail.length<lengthData4code){
lengthData4code = tail.length
lookInString = tail.substring(searchString.length, lengthData4code)
} else {
lookInString = tail.substring(searchString.length, searchString.length+lengthData4code) // data (part)string
}
if (lookInString.indexOf("$")>=0) { // string size is actually shorter than expected
lookInString = tail.substring(searchString.length,searchString.length+lookInString.indexOf("$"))
pos += (searchString.length + lookInString.length + 1)
} else {
pos += (searchString.length+ lengthData4code)
}
if (pos>=testPromptedEAN.length-1) {tail = ""}
else {tail = testPromptedEAN.substring(pos)}
if (searchString.contains("37", false)) {
//val eTMengeKomm = findViewById<EditText>(R.id.eTMengeKomm)
eTMengeKomm.setText(lookInString, TextView.BufferType.EDITABLE)
}
if (searchString.contains("10", false)) {
//val etCharge = findViewById<EditText>(R.id.eTCharge)
etCharge.setText(lookInString, TextView.BufferType.EDITABLE)
}
if (searchString.contains("15", false)) {
//val etMHD = findViewById<EditText>(R.id.eTMHD)
etMHD.setText(lookInString, TextView.BufferType.EDITABLE)
}
}
}
}
}
return super.dispatchKeyEvent(event)
}
非常感谢任何帮助。
我是如何解决这个问题的:
首先,我摆脱了重载的 dispachKeyEvent
方法。这在我的应用程序中造成了很多混乱,就我而言,后退和中间按钮根本没有反应。条形码 USB 扫描仪在 Android 中应该主要被识别为外部键盘,因此不需要此方法来将条形码捕获到特定的 EditText
字段中。之后,我将焦点设置在第一个 EditText
字段并在那里提示条形码。
其次,我了解到 while
循环 在活动的 UI 线程中不起作用 - 这就是原因,为什么我的应用程序一直在冻结。这就是为什么我在 Activity 中将 AsyncTask
实现为内部 class,并将所有后台处理逻辑放入 AsyncTask
的重载 doInBackround
方法中。在 onPostExecute
方法中,我为我的 EditText
字段设置了所有需要的值。
更新:我已经将整个后台逻辑提升到 ViewModel
中并最终摆脱了 AsyncTask
。