我最近尝试实现openalpr项目,该项目在其原始代码中运行良好。但是,当我尝试修改它并添加一些功能时,遇到了一些问题。
这是其部分代码:
AsyncTask.execute(new Runnable() {
@Override
public void run() {
String result = OpenALPR.Factory.create(MainActivity.this, ANDROID_DATA_DIR).recognizeWithCountryRegionNConfig("us", "", destination.getAbsolutePath(), openAlprConfFile, 10);
Log.d("OPEN ALPR", result);
try {
final Results results = new Gson().fromJson(result, Results.class);
runOnUiThread(new Runnable() {
@Override
public void run() {
if (results == null || results.getResults() == null || results.getResults().size() == 0) {
Toast.makeText(MainActivity.this, "It was not possible to detect the licence plate.", Toast.LENGTH_LONG).show();
resultTextView.setText("It was not possible to detect the licence plate.");
} else {
resultTextView.setText("Plate: " + results.getResults().get(0).getPlate()
// Trim confidence to two decimal places
+ " Confidence: " + String.format("%.2f", results.getResults().get(0).getConfidence()) + "%"
// Convert processing time to seconds and trim to two decimal places
+ " Processing time: " + String.format("%.2f", ((results.getProcessingTimeMs() / 1000.0) % 60)) + " seconds");
}
}
这很好。但是,当我尝试在runOnUiThread之前获取“结果”时,它无法正确检测到。
下面是我修改的代码:
AsyncTask.execute(new Runnable() {
@Override
public void run() {
String result = OpenALPR.Factory.create(MainActivity.this, ANDROID_DATA_DIR).recognizeWithCountryRegionNConfig("us", "", destination.getAbsolutePath(), openAlprConfFile, 10);
Log.d("OPEN ALPR", result);
try {
final Results results = new Gson().fromJson(result, Results.class);
if(results!=null) Log.d("ShowTheResults",results.getResults().get(0).getPlate());
runOnUiThread(new Runnable() {
@Override
public void run() {
if (results == null || results.getResults() == null || results.getResults().size() == 0) {
Toast.makeText(MainActivity.this, "It was not possible to detect the licence plate.", Toast.LENGTH_LONG).show();
resultTextView.setText("It was not possible to detect the licence plate.");
} else {
resultTextView.setText("Plate: " + results.getResults().get(0).getPlate()
// Trim confidence to two decimal places
+ " Confidence: " + String.format("%.2f", results.getResults().get(0).getConfidence()) + "%"
// Convert processing time to seconds and trim to two decimal places
+ " Processing time: " + String.format("%.2f", ((results.getProcessingTimeMs() / 1000.0) % 60)) + " seconds");
}
}
我只是不知道为什么输出将不同于UI线程。在我将其显示在UI上之前,谁能告诉我如何在后台正确使用“结果”?
最佳答案
我认为您使用AsyncTask
的方式非常糟糕。您要在异步线程上执行Runnable
,然后在其中调用runOnUiThread
以在UI线程上处理结果。为什么不按原意使用AsyncTask
的方式使用它们呢?
创建一个新任务,并使用其常见方法:doInBackground
,onProgressUpdate
,onPostExecute
。如果AsyncTask是在主线程上执行的,则最后两个已在UI线程上调用。
new AsyncTask<Void, Void, Results>() {
@Override
protected Results doInBackground(Void... params) {
String result = OpenALPR.Factory.create(MainActivity.this, ANDROID_DATA_DIR).recognizeWithCountryRegionNConfig("us", "", destination.getAbsolutePath(), openAlprConfFile, 10);
Log.d("OPEN ALPR", result);
Results results = new Gson().fromJson(result, Results.class);
if (results != null || results.getResults() != null || results.getResults().size() > 0)
Log.d("ShowTheResults", results.getResults().get(0).getPlate());
return results;
}
@Override
protected void onPostExecute(Results result) {
if (results == null || results.getResults() == null || results.getResults().size() == 0) {
Toast.makeText(MainActivity.this, "It was not possible to detect the licence plate.", Toast.LENGTH_LONG).show();
resultTextView.setText("It was not possible to detect the licence plate.");
} else {
resultTextView.setText("Plate: " + results.getResults().get(0).getPlate()
// Trim confidence to two decimal places
+ " Confidence: " + String.format("%.2f", results.getResults().get(0).getConfidence()) + "%"
// Convert processing time to seconds and trim to two decimal places
+ " Processing time: " + String.format("%.2f", ((results.getProcessingTimeMs() / 1000.0) % 60)) + " seconds");
}
}
}.execute();