2012-10-09 61 views
2

我的AsyncTask运行两次时,我的片段重新连接运行两次。我怎样才能让它只连接一次。这会导致内容视图尚未创建,当它在运行我的asynctask时,在标签之间快速切换。任何人都可以解决这个问题吗?的Android的AsyncTask在片段标签

public class AndroidFragment extends SherlockListFragment implements ActionBar.TabListener{ 

static final String URL = "https://xml.xml"; 
static final String KEY_SONG = "song"; 
static final String KEY_ID = "id"; 
static final String KEY_TITLE = "title"; 
static final String KEY_CAT_ARTIST = "artistcat"; 
static final String KEY_DURATION = "duration"; 
static final String KEY_THUMB_URL = "thumb_url"; 
static final String KEY_BIG_URL = "big_url"; 
static final String KEY_CAT_URL = "cat_url"; 
static final String KEY_DESC = "cat_desc"; 
ArrayList<HashMap<String, String>> menuItems; 
ListAdapter adapter; 
Context appContext; 
private Fragment mFragment; 

@Override 
public void onViewCreated(View view, Bundle savedInstanceState) { 


     new loadListView().execute(); 

     if (getActivity() != null) { 
      adapter=new MainPageLazyAdapter(getActivity(), menuItems); 
      setListAdapter(adapter);} 

    super.onViewCreated(view, savedInstanceState); 
     } 

public class loadListView extends AsyncTask<Integer, String, String> { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
    } 

    @Override 
    protected String doInBackground(Integer... args) { 
     // updating UI from Background Thread 
     menuItems = new ArrayList<HashMap<String, String>>(); 


     XMLParser parser = new XMLParser(); 
     String xml = parser.getXmlFromUrl(URL); // getting XML 
     Document doc = parser.getDomElement(xml); // getting DOM element 

     NodeList nl = doc.getElementsByTagName(KEY_SONG); 
     // looping through all item nodes <item> 
     for (int i = 0; i < nl.getLength(); i++) { 
      // creating new HashMap 
      HashMap<String, String> map = new HashMap<String, String>(); 
      Element e = (Element) nl.item(i); 
      // adding each child node to HashMap key => value 
      map.put(KEY_ID, parser.getValue(e, KEY_ID)); 
      map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE)); 
      map.put(KEY_CAT_ARTIST, parser.getValue(e, KEY_CAT_ARTIST)); 
      map.put(KEY_DURATION, parser.getValue(e, KEY_DURATION)); 
      map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL)); 
      map.put(KEY_BIG_URL, parser.getValue(e, KEY_BIG_URL)); 
      map.put(KEY_CAT_URL, parser.getValue(e, KEY_CAT_URL)); 
      map.put(KEY_DESC, parser.getValue(e, KEY_DESC)); 
      // adding HashList to ArrayList 
      menuItems.add(map); 
     } 
      return null; 
     } 


    @Override 
    protected void onPostExecute(String args) { 

    } 
} 

    @Override 
    public void onTabSelected(Tab tab, FragmentTransaction ft) { 

     if (mFragment == null) { 
      mFragment = new AndroidFragment(); 
      ft.add(android.R.id.content, mFragment); 
      //ft.attach(mFragment); 

     } else { 

      if (mFragment.isDetached()){ 
       ft.attach(mFragment); 
      } 


     } 
     } 


    @Override 
    public void onTabUnselected(Tab tab, FragmentTransaction ft) { 

     ft.detach(mFragment); 

    } 

    @Override 
    public void onTabReselected(Tab tab, FragmentTransaction ft) { 

    } 


} 

的logcat:

10-09 15:21:47.141: E/AndroidRuntime(7582): FATAL EXCEPTION: main 
10-09 15:21:47.141: E/AndroidRuntime(7582): java.lang.RuntimeException: Unable to start activity ComponentInfo{in.wptrafficanalyzer.actionbarsherlocknavtab/in.wptrafficanalyzer.actionbarsherlocknavtab.MainActivity}: java.lang.NullPointerException 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1970) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1995) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.app.ActivityThread.access$600(ActivityThread.java:127) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1161) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.os.Handler.dispatchMessage(Handler.java:99) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.os.Looper.loop(Looper.java:137) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.app.ActivityThread.main(ActivityThread.java:4512) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at java.lang.reflect.Method.invokeNative(Native Method) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at java.lang.reflect.Method.invoke(Method.java:511) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:982) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at dalvik.system.NativeStart.main(Native Method) 
10-09 15:21:47.141: E/AndroidRuntime(7582): Caused by: java.lang.NullPointerException 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at in.wptrafficanalyzer.actionbarsherlocknavtab.MainPageLazyAdapter.getCount(MainPageLazyAdapter.java:34) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.widget.ListView.setAdapter(ListView.java:460) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.support.v4.app.ListFragment.setListAdapter(ListFragment.java:182) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.support.v4.app.ListFragment.ensureList(ListFragment.java:365) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.support.v4.app.ListFragment.onViewCreated(ListFragment.java:145) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at in.wptrafficanalyzer.actionbarsherlocknavtab.AndroidFragment.onViewCreated(AndroidFragment.java:52) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:884) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:622) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1416) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:505) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1136) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.app.Activity.performStart(Activity.java:4475) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1943) 
10-09 15:21:47.141: E/AndroidRuntime(7582):  ... 11 more 
+0

邮完整的代码。否则,我们无法帮助你。 –

+0

我刚编辑过。请查看Trickster –

回答

2

你肯定的AsyncTask运行两次?因为我从代码和logcat中得到的是当AsyncTask完成并且onPostExecute被调用时(考虑到你的片段当前被分离),如果当时没有创建列表时调用setListAdapter,你会得到这个异常。因此,不要在onPostExecute中调用setListAdapter,而是将下载的项目保存在片段中,并将其设置为onViewCreated()中的适配器。试试看,告诉我这是否解决了你的问题。

使用此代码。

public class AndroidFragment extends SherlockListFragment implements ActionBar.TabListener{ 

    static final String URL   = "https://xml.xml"; 
    static final String KEY_SONG  = "song"; 
    static final String KEY_ID   = "id"; 
    static final String KEY_TITLE  = "title"; 
    static final String KEY_CAT_ARTIST = "artistcat"; 
    static final String KEY_DURATION = "duration"; 
    static final String KEY_THUMB_URL = "thumb_url"; 
    static final String KEY_BIG_URL = "big_url"; 
    static final String KEY_CAT_URL = "cat_url"; 
    static final String KEY_DESC  = "cat_desc"; 
    ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>; 
    ListAdapter adapter; 
    Context  appContext; 
    private Fragment mFragment; 

    @Override 
    public void onViewCreated (View view, Bundle savedInstanceState) { 


     new loadListView().execute(); 

     if (getActivity() != null) { 
      adapter = new MainPageLazyAdapter(getActivity(), menuItems); 
      setListAdapter(adapter); 
     } 

     super.onViewCreated(view, savedInstanceState); 
    } 

    public class loadListView extends AsyncTask<Integer, String, String> { 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
     } 

     @Override 
     protected String doInBackground (Integer... args) { 
      // updating UI from Background Thread 
      menuItems = new ArrayList<HashMap<String, String>>(); 


      XMLParser parser = new XMLParser(); 
      String xml = parser.getXmlFromUrl(URL); // getting XML 
      Document doc = parser.getDomElement(xml); // getting DOM element 

      NodeList nl = doc.getElementsByTagName(KEY_SONG); 
      // looping through all item nodes <item> 
      for (int i = 0; i < nl.getLength(); i++) { 
       // creating new HashMap 
       HashMap<String, String> map = new HashMap<String, String>(); 
       Element e = (Element) nl.item(i); 
       // adding each child node to HashMap key => value 
       map.put(KEY_ID, parser.getValue(e, KEY_ID)); 
       map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE)); 
       map.put(KEY_CAT_ARTIST, parser.getValue(e, KEY_CAT_ARTIST)); 
       map.put(KEY_DURATION, parser.getValue(e, KEY_DURATION)); 
       map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL)); 
       map.put(KEY_BIG_URL, parser.getValue(e, KEY_BIG_URL)); 
       map.put(KEY_CAT_URL, parser.getValue(e, KEY_CAT_URL)); 
       map.put(KEY_DESC, parser.getValue(e, KEY_DESC)); 
       // adding HashList to ArrayList 
       menuItems.add(map); 
      } 
      return null; 
     } 


     @Override 
     protected void onPostExecute (String args) { 
      if (adapter != null) adapter.notifyDataSetChanged(); 
     } 
    } 

    @Override 
    public void onTabSelected (Tab tab, FragmentTransaction ft) { 

     if (mFragment == null) { 
      mFragment = new AndroidFragment(); 
      ft.add(android.R.id.content, mFragment); 
      //ft.attach(mFragment); 

     } else { 

      if (mFragment.isDetached()) { 
       ft.attach(mFragment); 
      } 


     } 
    } 


    @Override 
    public void onTabUnselected (Tab tab, FragmentTransaction ft) { 

     ft.detach(mFragment); 

    } 

    @Override 
    public void onTabReselected (Tab tab, FragmentTransaction ft) { 

    } 


} 
+0

对不起Trickster,我不确定我是否正确执行此操作。我遇到了一个错误。请检查我的代码和我的logcat。 –

+0

我从来没有使用过notifyDataSetChanged。不知何故,当我尝试你的代码时,我得到了这个错误。方法notifyDataSetChanged()对于类型ListAdapter是未定义的 –

+0

什么是适配器的父类? –

0

我认为这并没有在那里,尝试将其删除:你类的

else { 

     if (mFragment.isDetached()){ 
      ft.attach(mFragment); 
     } 
+1

你能否提供更全面的解释来帮助OP? – Fiver