我已经实现了从网上下载数据然后在两个ActionBar.Tab
中显示的应用程序。我有一个问题。如果我从一个选项卡切换到另一个选项卡,应用程序启动另一个下载,并且在下载未完成时,应用程序冻结。如果互联网连接速度很慢,那就非常烦人了。我决定向应用添加ProgressDialog
以向用户显示该应用正在从网上下载数据。我添加了一段实现ProgressDialog
到AsyncTask
执行下载的代码,但这没有帮助。我理解为什么会发生这种情况,但无法找到解决问题的方法:(
将装入选项卡的数据表示为Fragment
类的实例。创建后的此实例将添加到transaction
,并且只有在将mFragment
对象添加到transaction
后,才会切换到另一个标签。
这是tabListener
代码的一部分:
// ...
@Override
public void onTabSelected(Tab tab, FragmentTransaction transaction) {
if (mFragment == null) {
/*
* Creation of ParkFragment is the reason why app locks!! Because in
* ParkFragment data is being downloaded from web
*/
mFragment = new ParkFragment(mUrl, mActivity);
/*
* mFragment can't be added to transaction until downloading is
* finished, that's why app doesn't switch fast
*/
transaction.add(android.R.id.content, mFragment, mTag);
} else {
transaction.attach(mFragment);
}
}
如果有人有任何想法如何实施ProgressDialog
以避免在标签之间切换延迟,请与之分享。
感谢您的阅读。
更新:我已阅读此问题的答案,但不明白该实施将如何帮助我管理延迟:Changing Tabs is Slow/Laggy - Using Fragments。
UPD:
public class ParkFragment extends ListFragment {
private ArrayList<Cinemas> cinema;
private CinemasAdapter cinemaAdapter;
private String url;
private Activity activity;
public ParkFragment (String cinema,Activity activ){
url = cinema;
activity = activ;
}
public void onCreate(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
cinema = new Handler().handle(url,activity);
cinemaAdapter = new CinemasAdapter(activity, R.layout.movie_data_row, cinema);
setListAdapter(cinemaAdapter);
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
Cinemas movie = cinemaAdapter.getItem(position);
Intent intent = new Intent (activity, More.class);
intent.putExtra("Cinemas", movie);
intent.putExtra("data", movie.getBitmap());
Bundle translateBundle =
ActivityOptions.makeCustomAnimation(activity,
R.anim.slide_in_left, R.anim.slide_out_left).toBundle();
startActivity (intent, translateBundle);
}
}
答案 0 :(得分:1)
在ParkFragment
中,您可以content providers与loaders结合使用。下载数据应在service中处理,完成后服务通过内容提供商将数据插入数据库。在你的片段中,加载器将加载数据。
在任何Android模拟器中都有一个名为API Demos的应用程序,它有几个与内容提供程序/加载器/服务相关的示例...其源代码可在Android SDK中找到,位于:[Android SDK]/samples/android-x/ApiDemos
,其中{ {1}}是API级别。
我只是这么认为,但如果您可以分享x
的代码,可能会出现另一个问题?
被修改
在ParkFragment
中,您可以创建ResultReceiver
(API 3+中提供),将其放入ParkFragment
并启动服务以下载/处理Intent
}。该服务会保留url
的实例,完成后会通过send(int, Bundle)
将下载的数据发送回您的片段。 Bundle
可以保存基本数据类型,例如ResultReceiver
,String
,int
...对于更复杂的数据,您可以创建一个类来保存它,实现Parcelable
或Serializable
。
或者使用Bound Services,您可以直接从片段中调用服务的方法。请注意,服务在主UI线程上运行,因此为了避免使用NetworkOnMainThreadException
,您需要在服务中使用byte[]
。