Асинхронная задача не может получить доступ к исходной теме - PullRequest
0 голосов
/ 09 ноября 2018

Я переместил свой код в асинхронную задачу, чтобы выполнить операцию в фоновом потоке.Код ниже:

public class AsynTaskActivity  extends  AsyncTask<HashMap<String, Integer>, Void, Void>
{

    @Override
    protected Void doInBackground(HashMap<String, Integer>... hashMaps)
    {

        HashMap<String, Integer> maps = hashMaps[0];
        //
        Set set = maps.entrySet();
        for (Object aSet : set)
        {
            Map.Entry entry = (Map.Entry) aSet;

            receiveBarcode(entry.getKey().toString());
        }
        return null;
    }
}

Однако при запуске базы кода.Я сталкиваюсь со следующей ошибкой:

Process: com.touchsides.checkout.debug, PID: 7447
java.lang.RuntimeException: An error occurred while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:309)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
    at java.util.concurrent.FutureTask.run(FutureTask.java:242)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
    at java.lang.Thread.run(Thread.java:818)
 Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6556)
    at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:942)

Я бы предположил, что doInbackground работает в отдельном потоке, и этой ошибки не должно быть.

Ответы [ 3 ]

0 голосов
/ 09 ноября 2018

В AsyncTask вы никогда не сможете выполнять взаимодействие с пользовательским интерфейсом в doInBackgound, однако вы все равно можете обновить свой пользовательский интерфейс, если передадите прогресс или результат в onProgressUpdate и onPostExecute соответственно, и таким образом вы восстановите поток пользовательского интерфейса. Вы можете попробовать изменить AsyncTask на что-то вроде:

public class AsynTaskActivity extends AsyncTask<HashMap<String, Integer>, String, Object> {

    @Override
    protected Object doInBackground(HashMap<String, Integer>... hashMaps) {
        // non-ui thread
        HashMap<String, Integer> maps = hashMaps[0];
        Set set = maps.entrySet();
        for (Object aSet : set) {
            Map.Entry entry = (Map.Entry) aSet;
            publishProgress(entry.getKey().toString()); // onProgressUpdate callback
        }
        return null; // onPostExecute callback
    }

    @Override
    protected void onProgressUpdate(String... progress) {
        // ui thread
        receiveBarcode(progress);
    }

    @Override
    protected void onPostExecute(Long result) {
        // ui thread
    }
}

AsyncTask хорошо задокументировано, вы можете прочитать об этом больше онлайн.

0 голосов
/ 09 ноября 2018

Переопределите onPostExecute() метод в вашем AsyncTask и выполняйте там пользовательский интерфейс.

Если вы действительно хотите изменить интерфейс в методе doInBackground(), тогда вы можете использовать Handler для этого.

0 голосов
/ 09 ноября 2018

Используйте runOnUiThread() для ссылки на действие

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...