Работая на UIThread и публикуя для просмотра, все равно получите CalledFromWrongThreadException
Название говорит обо всем. Ну в основном. Это происходит только на 1 устройстве. Другие устройства в порядке.
в onPostExecute
из AsyncTask
Я вызываю код ниже, прежде чем получить это исключение, у меня не былоrunOnUiThread
, runnable был добавлен, потому что я получаю исключение CalledFromWrongThreadException.
РЕДАКТИРОВАТЬ
Вот что я обнаружил. В определенных обстоятельствах приложение может иметь более одного "петлителя" и, следовательно, более одного "потока пользовательского интерфейса".
Поскольку приложение может иметь более одного "потока пользовательского интерфейса" и AsyncTask всегда "выполняется в потоке пользовательского интерфейса" [ref], кто-то решил [плохо], что вместо AsyncTask всегда выполняется в потоке создания (что в 99,9999999% случаев было бы правильным "потоком пользовательского интерфейса") они решили использовать фокус-покус (или неудачно созданный ярлык, вы решаете) для выполнения на "главном петлителе"..
Android: получил CalledFromWrongThreadException в onPostExecute() - как это может быть?
Так что теперь мне нужно найти способ убедиться, что поток асинхронных задач всегда является лупером, в котором находится приложение:(
getParentActivity().runOnUiThread(new Runnable()
{
@Override
public void run()
{
setAdapterData(result);
}
});
когда это не сработало, я тоже попробовал и попробовал их вместе.
lvUpdatesList.post(new Runnable()
{
@Override
public void run()
{
lvUpdatesList.setAdapter(updateListAdapter);
}
});
Я очень запутался, почему он так себя ведет.
07-03 13:19:51.908: E/AndroidRuntime(4479): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.view.ViewRoot.checkThread(ViewRoot.java:2932)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.view.ViewRoot.invalidateChild(ViewRoot.java:642)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:668)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.view.ViewGroup.invalidateChild(ViewGroup.java:2511)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.view.View.invalidate(View.java:5279)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.widget.AbsListView.resetList(AbsListView.java:1120)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.widget.ListView.resetList(ListView.java:511)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.widget.ListView.setAdapter(ListView.java:440)
07-03 13:19:51.908: E/AndroidRuntime(4479): at com.********.********.FragmentUpdates.setAdapterData(FragmentUpdates.java:213)
07-03 13:19:51.908: E/AndroidRuntime(4479): at com.********.********.FragmentUpdates$AsyncGetUpdates.onPostExecute(FragmentUpdates.java:185)
07-03 13:19:51.908: E/AndroidRuntime(4479): at com.********.********.FragmentUpdates$AsyncGetUpdates.onPostExecute(FragmentUpdates.java:1)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.os.AsyncTask.finish(AsyncTask.java:417)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.os.AsyncTask.access$300(AsyncTask.java:127)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.os.Handler.dispatchMessage(Handler.java:99)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.os.Looper.loop(Looper.java:130)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.os.HandlerThread.run(HandlerThread.java:60)
полная асинктаск
class AsyncGetUpdates extends AsyncTask<Void, Void, List<UpdateDTO>>
{
String userId;
@Override
protected void onPreExecute()
{
showDialog();
userId = getParentActivity().getCurrentUser().getUser_id();
super.onPreExecute();
}
@Override
protected List<UpdateDTO> doInBackground(Void... params)
{
boolean followingOnly = false;
if (myState == MyState.Following)
followingOnly = true;
return APIHelper.getUpdates(userId, followingOnly, count);
}
@Override
protected void onPostExecute(final List<UpdateDTO> result)
{
killDialog();
isCurrentlyUpdating = false;
getParentActivity().runOnUiThread(new Runnable()
{
@Override
public void run()
{
setAdapterData(result);
}
});
super.onPostExecute(result);
}
}
1 ответ
На будущее, если у людей есть эта проблема, которая у вас не возникает на каких-либо пост-устройствах JellyBean, это то, как вы ее исправите.
Самое первое, что вы делаете в своем приложении - это.
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_splash);
this.runOnUiThread(new Runnable()
{
@Override
public void run()
{
new AsyncInitLooperTask().execute();
}
});
}
public class AsyncInitLooperTask extends AsyncTask<Void, Void, Void>
{
@Override
protected Void doInBackground(Void... params)
{
return null;
}
}
К чему это будет приложить InternalHandler
это относится к AsyncTasks для вашего приложения к правильному Looper/UIThread, который ваше приложение использует.