繁体   English   中英

如何解决“无法在尚未调用Looper.prepare()的线程内创建处理程序”的问题?

[英]How to overcome “Can't create handler inside thread that has not called Looper.prepare()” issue?

我正在尝试在viewpager中创建片段。 在适配器中,我使用线程来创建片段。 在线程内部,我正在执行AsyncTask,它进一步获取片段。 在每个片段类(OneFragment,TwoFragment)中,我都有AsyncTask,它们可以从Web访问一些API。 如果我根本不使用线程和AsyncTask,则该应用程序效果很好。 我正在使用它来提高UI性能。 但这是在获取错误。 我已经讨论了关于同一问题的一些已经存在的主题。 但是我不知道原因。 谁能指出我在这里做错了什么?

这是我的适配器类和AsyncTask类:

class SectionsPagerAdapter extends FragmentStatePagerAdapter {
     Activity activity;
     Fragment f = null;
public SectionsPagerAdapter(FragmentManager fm, Activity activity) {
    super(fm);
    this.activity = activity;
}

@Override
public Fragment getItem(int i) {        
    switch (i) {
    case 0: {           
        activity.runOnUiThread(new Runnable() {
            public void run() {
        try {
             f =  new FetchFragment().execute("one").get();             
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
            }
        });             
        return f;
    }
    case 1: {
        activity.runOnUiThread(new Runnable() {
            public void run() {
        try {
             f =  new FetchFragment().execute("two").get();             
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
            }
        });             
        return f;
    }
    }
    return null;
}

@Override
public int getCount() {
    return 2;
}

@Override
public CharSequence getPageTitle(int position) {
    switch (position) {
    case 0:
        return "one";
    case 1:
        return "two";
    }
    return null;
}


class FetchFragment extends AsyncTask<String, Void, Fragment>
{   
@Override
protected Fragment doInBackground(String... arg0) {     
    if(arg0[0].equalsIgnoreCase("one"))
    {
        Fragment fragment = new OneFragment();
        Bundle args = new Bundle();
        args.putInt(CategoriesFragment.ARG_SECTION_NUMBER, 1);
        fragment.setArguments(args);
        return fragment;
    }
    if(arg0[0].equalsIgnoreCase("two"))
    {
        Fragment fragment = new TwoFragment();
        Bundle args = new Bundle();
        args.putInt(FeaturedFragment.ARG_SECTION_NUMBER, 2);
        fragment.setArguments(args);
        return fragment;
    }       
    return null;
}

@Override
 protected void onPostExecute(Fragment fragment){}
}
}

这是我的错误日志。

10-23 12:52:28.835: E/AndroidRuntime(17485): FATAL EXCEPTION: AsyncTask #3
10-23 12:52:28.835: E/AndroidRuntime(17485): java.lang.RuntimeException: An error occured while executing doInBackground()
10-23 12:52:28.835: E/AndroidRuntime(17485):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
10-23 12:52:28.835: E/AndroidRuntime(17485):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
10-23 12:52:28.835: E/AndroidRuntime(17485):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
10-23 12:52:28.835: E/AndroidRuntime(17485):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
10-23 12:52:28.835: E/AndroidRuntime(17485):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
10-23 12:52:28.835: E/AndroidRuntime(17485):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
10-23 12:52:28.835: E/AndroidRuntime(17485):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
10-23 12:52:28.835: E/AndroidRuntime(17485):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
10-23 12:52:28.835: E/AndroidRuntime(17485):    at java.lang.Thread.run(Thread.java:856)
10-23 12:52:28.835: E/AndroidRuntime(17485): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
10-23 12:52:28.835: E/AndroidRuntime(17485):    at android.os.Handler.<init>(Handler.java:121)
10-23 12:52:28.835: E/AndroidRuntime(17485):    at android.support.v4.app.ListFragment.<init>(ListFragment.java:47)
10-23 12:52:28.835: E/AndroidRuntime(17485):    at com.store.fragments.OneFragment.<init>(OneFragment.java:68)
10-23 12:52:28.835: E/AndroidRuntime(17485):    at com.store.adapter.SectionsPagerAdapter$FetchFragment.doInBackground(SectionsPagerAdapter.java:173)
10-23 12:52:28.835: E/AndroidRuntime(17485):    at com.store.adapter.SectionsPagerAdapter$FetchFragment.doInBackground(SectionsPagerAdapter.java:1)
10-23 12:52:28.835: E/AndroidRuntime(17485):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
10-23 12:52:28.835: E/AndroidRuntime(17485):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)

好的,您使用asynctasks做错了。 通常,异步任务用于一些耗时的操作,这些操作应该在后台处理,但是您试图在UiThread上运行它。 并且在asynctask中,您尝试在doInBackground()中修改UI,但强烈建议在onPostExecute()中进行修改

您不应该在AsyncTask的doInBackground()进行任何UI更新。所有UI操作必须在onPostExecute() 了解更多在这里学习

也看我以前的帖子

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM