0

我想在viewpager中創建片段。在適配器中,我使用線程來創建片段。內部線程我正在執行AsyncTask,它進一步獲取片段。在每個片段類(OneFragment,TwoFragment)中,我有AsyncTask,它可以從Web訪問一些API。如果我根本不使用線程和AsyncTask,應用程序工作正常。我正在使用這個平滑的UI性能。但它正在提取錯誤。我已經瀏覽了一些關於同一問題的已有話題。但我無法弄清楚這個原因。任何人都可以指出我在這裏做錯了什麼?如何克服「不能在沒有調用Looper.prepare()」問題的線程中創建處理程序?

這是我的適配器類和類的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) 

回答

2

好吧,你這樣做是不對的asynctasks。通常,asynctasks用於需要在後臺處理的一些耗時的操作,但是你試圖在UiThread上運行它。並且在asynctask中,您嘗試修改doInBackground()中的UI,但強烈建議在onPostExecute()中執行此操作。

1

你不應該做的AsyncTask的doInBackground()。所有的UI操作任何UI updations必須在onPostExecute()。要了解更多Study here

見我以前Post

+3

誰說我們不能在doInBackground()內執行UI更新。是的,我知道它不可取,但我們可以使用'runOnUiThread'來實現。 –

+0

@PareshMayani :)謝謝,但爲什麼要在doInBackground()中使用runOnUiThred()。你能告訴一個案子嗎? – Abhi

+0

這就是我使用runOnUiThread的原因。但我仍然遇到問題。這是因爲嵌套的AsyncTasks?我的意思是在AsyncTask裏面我創建了一個片段,它裏面有一些AsyncTask。這是原因嗎? – intrepidkarthi

相關問題