我为一些网站制作了一些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帧!应用程序可能在其主线程上做了太多工作。
我认为这是因为这一点。无论如何,我可以从我的片段类中的onPostExecute获取该提要吗? – Zookey
@Zookey:一种方法是让'AsyncTask'成为正在讨论的片段的内部类,并将片段标记为'setRetainInstance(true)'。然后,您可以根据需要使用'onPostExecute()'中的片段调用方法,同时使用'setRetainInstance(true)'确保片段在配置更改期间保持不变。或者,开始使用某种消息总线('LocalBroadcastManager',Square的Otto,greenrobot的EventBus等),并从'onPostExecute()'发送一条消息以供片段拾取(如果它仍然在)。 – CommonsWare
听起来很复杂! :)有什么好的例子与异步任务和片段的工作? – Zookey