2013-07-09 40 views
3

我爲一些網站製作了一些RSS閱讀器,所以我想在較低版本的Androd 4.0上實現actionbar和viewpager,所以我使用ActionBarSherlock和ViewPagerIndicator傑克沃頓,所以我正在處理碎片。Android AsyncTask:跳過X幀 - 在主線程內工作太多

我想從URL讀取一些RSS提要,並且我爲那個名爲LoadXMLData的AsyncTask類,這裏是該類的代碼。

LoadXMLData類:

public class LoadXMLData extends AsyncTask<String, RSSFeed, RSSFeed>{ 


private ProgressDialog mProgressDialog; 


private Context context; 
RSSFeed feed; 
private String RSSFEEDURL = "http://balkanandroid.com/feed/"; 

public LoadXMLData(Context context) { 
    this.context = context; 
    mProgressDialog = new ProgressDialog(context); 
    mProgressDialog.setMessage("Molimo Vas, sačekajte. Podaci se učitavaju."); 
} 

@Override 
protected void onPreExecute() { 
    super.onPreExecute(); 
    mProgressDialog.show(); 
    Log.d("OVDE SAM:", "onPreExecute()"); 
} 

@Override 
protected RSSFeed doInBackground(String... urls) { 
    // Obtain feed 
    DOMParser myParser = new DOMParser(); 
    feed = myParser.parseXml(urls[0]); 
    Log.d("OVDE SAM:", "PARSIRAM XML"); 
    return feed; 
} 



@Override 
protected void onPostExecute(RSSFeed result) { 
    mProgressDialog.dismiss(); 
    super.onPostExecute(result); 
} 

}

另外我有類MainActivity,其延伸SherlockFragmentActivity。

public class MainActivity extends SherlockFragmentActivity { 
BAFragmentAdapter mAdapter; 
RSSFeed feed; 
Application myApp; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    Log.d("OVDE SAM:", "MAIN ACTIVITY"); 

    myApp = getApplication(); 



    mAdapter = new BAFragmentAdapter(getSupportFragmentManager()); 

    ViewPager pager = (ViewPager) findViewById(R.id.pager); 
    pager.setAdapter(mAdapter); 

    TabPageIndicator indicator = (TabPageIndicator) findViewById(R.id.indicator); 
    indicator.setViewPager(pager); 

} 

public RSSFeed getFeed() { 
    return feed; 
} 

public void setFeed(RSSFeed feed) { 
    this.feed = feed; 
} 

而最imporatnt我有幾個片段類(LatestFragments,PhonesFragments,TabletFragments,ApplicationFragments等),並在每個片段我有幾乎相同的代碼如下所示。

這裏是LatestFragment的完整代碼:

public class LatestFragment extends Fragment { 

GridView lv; 
RSSFeed feed; 
CustomListAdapter adapter; 
private String RSSFEEDURL = "http://balkanandroid.com/feed/"; 

public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.fragment_najnovije, container, 
      false); 


    AsyncTask<String, RSSFeed, RSSFeed> xml = new LoadXMLData(getActivity()) 
      .execute(RSSFEEDURL); 

    // AsyncTask<String, RSSFeed, RSSFeed> load = new 
    // LoadXMLData(getActivity()).execute(RSSFEEDURL); 

    try { 
     feed = xml.get(); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (ExecutionException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    lv = (GridView) view.findViewById(R.id.GridView1); 

    // Set an Adapter to the ListView 
    adapter = new CustomListAdapter(); 
    lv.setAdapter(adapter); 

    // Set on item click listener to the ListView 
    lv.setOnItemClickListener(new OnItemClickListener() { 

     public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, 
       long arg3) { 
      // actions to be performed when a list item clicked 
      int pos = arg2; 

      Bundle bundle = new Bundle(); 
      bundle.putSerializable("feed", feed); 
      Intent intent = new Intent(getActivity(), DetailsActivity.class); 
      intent.putExtras(bundle); 
      intent.putExtra("pos", pos); 
      startActivity(intent); 

     } 
    }); 

    return view; 
} 

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    adapter.imageLoader.clearCache(); 
    adapter.notifyDataSetChanged(); 
} 

class CustomListAdapter extends BaseAdapter { 

    private LayoutInflater layoutInflater; 
    public ImageLoader imageLoader; 

    public CustomListAdapter() { 

     layoutInflater = (LayoutInflater) getActivity().getSystemService(
       Context.LAYOUT_INFLATER_SERVICE); 
     imageLoader = new ImageLoader(getActivity().getApplicationContext()); 
    } 

    public int getCount() { 
     // TODO Auto-generated method stub 
     // Set the total list item count 
     return feed.getItemCount(); 
    } 

    public Object getItem(int arg0) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    public long getItemId(int arg0) { 
     // TODO Auto-generated method stub 
     return 0; 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 
     // Inflate the item layout and set the views 
     View listItem = convertView; 
     int pos = position; 
     if (listItem == null) { 
      listItem = layoutInflater.inflate(R.layout.list_item, null); 
     } 

     // Initialize the views in the layout 
     ImageView iv = (ImageView) listItem.findViewById(R.id.thumb); 
     TextView tvTitle = (TextView) listItem.findViewById(R.id.title); 
     TextView tvDate = (TextView) listItem.findViewById(R.id.tvDate); 

     // Set the views in the layout 
     imageLoader.DisplayImage(feed.getItem(pos).getImage(), iv); 
     tvTitle.setText(feed.getItem(pos).getTitle()); 
     tvDate.setText(feed.getItem(pos).getDate()); 

     return listItem; 
    } 

} 

}

正如你可以看到我用的AsyncTask類LoadXMLData讀取數據doInBackground()方法,然後我使用此代碼在所有片段類下調用AsyncTask類,因爲我需要RSSFeed的結果,因爲我需要該數據將其顯示給用戶。

AsyncTask<String, RSSFeed, RSSFeed> xml = new LoadXMLData(getActivity()) 
      .execute(RSSFEEDURL); 

    try { 
     feed = xml.get(); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (ExecutionException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

和它的作品,但是當我點擊從視圖尋呼機打開其他視圖的緩慢,幾乎凍結我的應用程序,和我得到的logcat此消息。

07-10 00:22:40.598:I/Choreographer(623):跳過了316幀!應用程序可能在其主線程上做了太多工作。

回答

3

這是因爲您在AsyncTask上撥打get(),哪個阻止。不要這樣做。

請改爲使用AsyncTask的中的Feed。

+0

我認爲這是因爲這一點。無論如何,我可以從我的片段類中的onPostExecute獲取該提要嗎? – Zookey

+0

@Zookey:一種方法是讓'AsyncTask'成爲正在討論的片段的內部類,並將片段標記爲'setRetainInstance(true)'。然後,您可以根據需要使用'onPostExecute()'中的片段調用方法,同時使用'setRetainInstance(true)'確保片段在配置更改期間保持不變。或者,開始使用某種消息總線('LocalBroadcastManager',Square的Otto,greenrobot的EventBus等),並從'onPostExecute()'發送一條消息以供片段拾取(如果它仍然在)。 – CommonsWare

+0

聽起來很複雜! :)有什麼好的例子與異步任務和片段的工作? – Zookey

相關問題