0

我正在尝试在 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)
4

2 回答 2

2

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

于 2012-10-23T07:48:01.123 回答
1

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

也可以看看我之前的帖子

于 2012-10-23T07:45:51.310 回答