运行在UIThread和张贴查看,仍然得到CalledFromWrongThreadException [英] Running on UIThread and posting to view, still get CalledFromWrongThreadException

查看:178
本文介绍了运行在UIThread和张贴查看,仍然得到CalledFromWrongThreadException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

标题说明了一切。那么居多。这仅发生1设备上。其他设备都很好。

onPostExecute A 的AsyncTask 我打电话低于code,前获得这个例外,我没有足够的 runOnUiThread ,可运行的加入,因为我收到CalledFromWrongThreadException例外。


修改

下面是我发现。在某些情况下,应用程序可以有一个以上的弯,因此一个以上的UI线程

因为一个应用程序可以有多个UI线程和一个AsyncTask的始终[参考]在UI线程上运行,有人决定[不良],与其在AsyncTask的总是它的创建线程运行(这99.999999 %的病例是正确的UI线程),他们决定使用骗人把戏(或制作不良的快捷方式,你决定)对主尺蠖执行..

<一个href=\"http://stackoverflow.com/questions/10426120/android-got-calledfromwrongthreadexception-in-onpostexecute-how-could-it-be\">Android:有CalledFromWrongThreadException在onPostExecute() - ?这怎么可能

看起来是这样的,现在我需要找到一种方法来确保异步任务线程总是弯针线的应用程序是:(


  getParentActivity()。runOnUiThread(新的Runnable()
{
        @覆盖
        公共无效的run()
        {
            setAdapterData(结果);
        }
});

当没有工作,我想这个问题,以及,并试图在一起。

  lvUpdatesList.post(新的Runnable()
{
    @覆盖
    公共无效的run()
    {
        lvUpdatesList.setAdapter(updateListAdapter);
    }
});

我,为什么它的行为就像这个超级困惑。

  07-03 13:19:51.908:E / AndroidRuntime(4479):android.view.ViewRoot $ CalledFromWrongThreadException:只有创建视图层次可以触摸其观点原来的线程。
07-03 13:19:51.908:E / AndroidRuntime(4479):在android.view.ViewRoot.checkThread(ViewRoot.java:2932)
07-03 13:19:51.908:E / AndroidRuntime(4479):在android.view.ViewRoot.invalidateChild(ViewRoot.java:642)
07-03 13:19:51.908:E / AndroidRuntime(4479):在android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:668)
07-03 13:19:51.908:E / AndroidRuntime(4479):在android.view.ViewGroup.invalidateChild(ViewGroup.java:2511)
07-03 13:19:51.908:E / AndroidRuntime(4479):在android.view.View.invalidate(View.java:5279)
07-03 13:19:51.908:E / AndroidRuntime(4479):在android.widget.AbsListView.resetList(AbsListView.java:1120)
07-03 13:19:51.908:E / AndroidRuntime(4479):在android.widget.ListView.resetList(ListView.java:511)
07-03 13:19:51.908:E / AndroidRuntime(4479):在android.widget.ListView.setAdapter(ListView.java:440)
07-03 13:19:51.908:E / AndroidRuntime(4479)。在COM ******** ******** FragmentUpdates.setAdapterData(FragmentUpdates.java:213)
07-03 13:19:51.908:E / AndroidRuntime(4479)。在COM ******** ******** FragmentUpdates $ AsyncGetUpdates.onPostExecute(FragmentUpdates.java:185)
07-03 13:19:51.908:E / AndroidRuntime(4479)。在COM ******** ******** FragmentUpdates $ AsyncGetUpdates.onPostExecute(FragmentUpdates.java:1)
07-03 13:19:51.908:E / AndroidRuntime(4479):在android.os.AsyncTask.finish(AsyncTask.java:417)
07-03 13:19:51.908:E / AndroidRuntime(4479):在android.os.AsyncTask.access $ 300(AsyncTask.java:127)
07-03 13:19:51.908:E / AndroidRuntime(4479):在android.os.AsyncTask $ InternalHandler.handleMessage(AsyncTask.java:429)
07-03 13:19:51.908:E / AndroidRuntime(4479):在android.os.Handler.dispatchMessage(Handler.java:99)
07-03 13:19:51.908:E / AndroidRuntime(4479):在android.os.Looper.loop(Looper.java:130)
07-03 13:19:51.908:E / AndroidRuntime(4479):在android.os.HandlerThread.run(HandlerThread.java:60)

全面的AsyncTask

 类AsyncGetUpdates扩展的AsyncTask&LT;太虚,太虚,列表与LT; UpdateDTO&GT;&GT;
    {        字符串userid;        @覆盖
        在preExecute保护无效()
        {
            的ShowDialog();
            用户id = getParentActivity()getCurrentUser()getUser_id()。
            super.on preExecute();
        }        @覆盖
        保护列表与LT; UpdateDTO&GT; doInBackground(虚空...... PARAMS)
        {
            布尔followingOnly = FALSE;
            如果(myState == MyState.Following)
                followingOnly = TRUE;            返回APIHelper.getUpdates(用户ID,followingOnly,计数);
        }        @覆盖
        保护无效onPostExecute(最终名单,LT; UpdateDTO&GT;结果)
        {
            killDialog();
            isCurrentlyUpdating = FALSE;
            getParentActivity()。runOnUiThread(新的Runnable()
            {
                @覆盖
                公共无效的run()
                {
                    setAdapterData(结果);
                }
            });
            super.onPostExecute(结果);
        }    }


解决方案

有关今后如果人有这样的问题,您可以在任何职位软糖设备惯于,你这是怎么解决它。

您在您的应用程序做的非常非常非常的第一件事情是这样的。

  @覆盖
保护无效的onCreate(捆绑savedInstanceState)
{
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    的setContentView(R.layout.activity_splash);    this.runOnUiThread(新的Runnable()
    {
        @覆盖
        公共无效的run()
        {
            新AsyncInitLooperTask()执行();
        }
    });
     }公共类AsyncInitLooperTask扩展的AsyncTask&LT;太虚,太虚,太虚&GT;
{
    @覆盖
    保护无效doInBackground(无效... PARAMS)
    {
        返回null;
    }
}

这将完成它附加 InternalHandler 与AsyncTasks交易为你的应用程序到正确的活套/ UIThread您的应用程序使用。

Title says it all. Well mostly. This is only happening on 1 device. Other devices are fine.

In the onPostExecute of a AsyncTask I am calling the code below, before getting this exception I did not have the runOnUiThread, the runnable was added because I am getting the CalledFromWrongThreadException exception.


EDIT

Here is what I have discovered. In certain circumstances an application can have more than one "looper" and therefore more than one "UI thread".

Since an application can have more than one "UI thread" and an AsyncTask always "Runs on the UI thread" [ref], someone decided [poorly] that instead of the AsyncTask always running on its creation thread (which in 99.999999% of cases would be the correct "UI thread") they decided to use hocus pocus (or a poorly crafted shortcut, you decide) to execute on the "main looper"..

Android: got CalledFromWrongThreadException in onPostExecute() - How could it be?

So it seems now I need to find a way to make sure the async tasks thread is always the looper thread the app is on :(


getParentActivity().runOnUiThread(new Runnable()
{
        @Override
        public void run()
        {
            setAdapterData(result);
        }
});

when that didn't work I tried this as well, and tried them together.

lvUpdatesList.post(new Runnable()
{
    @Override
    public void run()
    {
        lvUpdatesList.setAdapter(updateListAdapter);
    }
});

I am super confused as to why it is behaving like this.

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)

full asynctask

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);
        }

    }

解决方案

For the future if people have this issue, which you wont in any post JellyBean devices, this is how you fix it.

The very very very first thing you do in your app is this.

@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;
    }
}

What this will do it attach the InternalHandler that deals with AsyncTasks for you app to the correct Looper/UIThread that your app is using.

这篇关于运行在UIThread和张贴查看,仍然得到CalledFromWrongThreadException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆