运行在UIThread并发布查看,仍然得到CalledFromWrongThreadException [英] Running on UIThread and posting to view, still get CalledFromWrongThreadException

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

问题描述

标题说了一切。大多数这仅在1台设备上发生。其他设备都很好。



AsyncTask onPostExecute c>我正在调用下面的代码,在获取此异常之前,我没有 runOnUiThread ,runnable已添加,因为我收到了CalledFromWrongThreadException






编辑



这是我发现的。在某些情况下,应用程序可以有多个活套,因此可以有多个UI线程。



由于应用程序可以有多个UI线程和AsyncTask总是运行在UI线程[参考],有人决定[糟糕],而不是AsyncTask总是运行在其创建线程(在99.999999%的情况下将是正确的UI线程),他们决定使用hocus pocus(或者你精心设计的快捷方式,你决定)在主要的骑手上执行。



Android:在onPostExecute()中被CalledFromWrongThreadException - 怎么可能?



所以现在看来​​,我需要找到一种方法来确保异步任务线程始终是应用程序的欺骗线程:(






  getParentActivity()。runOnUiThread(new Runnable()
{
@Overrid e
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:只有创建视图层次结构的原始线程才能触摸它的意见。 
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.setAdapter数据(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):在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< 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;

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

}


解决方案



对于将来,如果有人遇到这个问题,您不会在任何发布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扩展AsyncTask< Void,Void,Void>
{
@Override
protected Void doInBackground(Void ... params)
{
return null;
}
}

这将附加 InternalHandler 将AsyncTasks应用程序应用于您的应用程序正在使用的Looper / 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天全站免登陆