Android Asynctask和runOnUiThread

时间:2017-03-13 08:48:50

标签: java android android-asynctask

我最近尝试实现了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");
                            }
                        }

这很好用。但当我试图获得"结果时#34;在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上显示它之前的背景中?

2 个答案:

答案 0 :(得分:0)

首先,我不确定您的异步任务实现,但我可以看到问题所在。请检查以下代码。

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 || results.getResults() != null || results.getResults().size() > 0) 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");
                            }
                        }

答案 1 :(得分:0)

我认为你以非常糟糕的方式使用AsyncTask。您希望在异步线程上执行Runnable,然后在其中调用runOnUiThread来处理UI线程上的结果。为什么不按照它们的使用方式使用AsyncTask

创建新任务并使用其常用方法:doInBackgroundonProgressUpdateonPostExecute。如果在主线程上执行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();