在下面的代码中,我选择了各自的标签时会显示两个片段。这两个片段都运行asynctasks,并且在它们这样做时应该显示进度对话框。第一个片段(ndi)显示其进度对话框,而片段bnf从不显示其进度对话框。为什么是这样?当我单击交换机中的案例1的选项卡时,当我的连接速度很慢并且屏幕冻结时,选项卡的切换非常慢。我认为ui线程被锁定在某个地方,但我不知道在哪里。如果您需要更多信息,请告诉我。感谢。
public class NasaAppActivity extends Activity implements ActionBar.TabListener{
private Bundle savedInstanceState;
private static View mainView;
private FragmentTransaction ft;
BreakingNewsFragment bnf;
NasaDailyImage ndi;
@Override
@Override
public void onStart(){
super.onStart();
if(savedInstanceState==null){
ndi=new NasaDailyImage(this);
bnf=new BreakingNewsFragment(this);
ft=getFragmentManager().beginTransaction();
ft.add(R.id.focused_view_container,ndi).commit();
getFragmentManager().executePendingTransactions();
ndi.onRefresh();
ft=getFragmentManager().beginTransaction();
ft.add(R.id.focused_view_container,bnf).commit();
getFragmentManager().executePendingTransactions();
}
}
public void onTabSelected(Tab tab, FragmentTransaction f) {
switch(tab.getPosition()){
case 0:
ft=getFragmentManager().beginTransaction();
ft.hide(bnf);
ft.show(ndi);
ft.commit();
getFragmentManager().executePendingTransactions();
break;
case 1:
ft=getFragmentManager().beginTransaction();
ft.hide(ndi);
ft.show(bnf);
ft.commit();
bnf.fetchStories();
getFragmentManager().executePendingTransactions();
break;
}
}
这是一个不起作用的进度对话框,应该在调用bnf.fetchStories()后显示
public class RssNewsParser extends AsyncTask<ArrayList<Story>,String,ArrayList<Story>>{
private ProgressDialog dialog;
private BreakingNewsFragment bnf;
private URL newsURL;
private ArrayList<Story> stories=new ArrayList<Story>();
private int eventType;
private int storyCount= -1;
private Activity mainActivity;
private ArrayList<String> storyTitles=new ArrayList<String>();
RssNewsParser(Activity mainActivity,BreakingNewsFragment bnf){
this.mainActivity=mainActivity;
this.bnf=bnf;
}
@Override
protected void onPostExecute(ArrayList<Story> result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
for(Story story:stories){
storyTitles.add(story.getTitle());
}
bnf.setListAdapter(new ArrayAdapter<String>(mainActivity,
android.R.layout.simple_list_item_1,storyTitles));
dialog.hide();
}
@Override
protected void onPreExecute() {
super.onPreExecute();
dialog=ProgressDialog.show(mainActivity, "Loading", "loading news");
}
这是一个有效的对话框,我感到困惑,因为它们的使用方式完全相同。当ndi.onRefresh()运行其asynctask时,会显示这个。
public class RssParseSync extends AsyncTask<String,String,Bitmap>{
private Context parent;
private ProgressDialog dialog;
private static Bitmap final_image; //must be static because a new instance is required to access getFinalImage();
private String imageURL="";
private static String imageName;
private long totalTime;
private long startTime;
private static View v;
private Activity mainActivity;
public RssParseSync(View v,Activity mainActivity){
this.v=v;
this.mainActivity=mainActivity;
String result=mainActivity.toString();
}
protected void onPostExecute(Bitmap image){
ImageView imageView=(ImageView) v.findViewById(R.id.imageDisplay);
imageView.setImageBitmap(image);
dialog.dismiss();
//this.cancel(true);
}
protected void onPreExecute(){
if(final_image!=null){
final_image.recycle();
}
nullAllViews();
dialog=ProgressDialog.show(mainActivity, "Loading", "Loading the image of the day");
}
private void nullAllViews(){
TextView titleView;
titleView=(TextView) v.findViewById(R.id.imageTitle);
titleView.setText(null);
TextView dateView=(TextView) v.findViewById(R.id.imageDate);
dateView.setText(null);
TextView descriptionView=(TextView) v.findViewById(R.id.imageDescription);
descriptionView.setText(null);
ImageView imageView=(ImageView) v.findViewById(R.id.imageDisplay);
imageView.setImageBitmap(null);
}
package com.wajumbie.nasadailyimage;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.net.Uri;
import android.os.Bundle;
import android.app.ListFragment;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
@SuppressLint("ValidFragment")
public class BreakingNewsFragment extends ListFragment {
private static Activity mainActivity;
private static ArrayList<Story> stories=new ArrayList<Story>();
private static ArrayList<String> storyTitles=new ArrayList<String>();
public BreakingNewsFragment(){
}
public BreakingNewsFragment(Activity mainActivity){
this.mainActivity=mainActivity;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onHiddenChanged(boolean hidden) {
// TODO Auto-generated method stub
super.onHiddenChanged(hidden);
}
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
String url = stories.get(position).getURL();
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
public void fetchStories(){
RssNewsParser parser=new RssNewsParser(mainActivity,this);
if(stories.isEmpty()){
parser.execute();
try {
stories=parser.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//stories=parser.getStories();
}
public void updateList(){
//String result;
//result = storyTitles.toString();
setListAdapter(new ArrayAdapter<String>(mainActivity,android.R.layout.simple_list_item_1,storyTitles));
}
@Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
}
public void onRefresh() {
fetchStories();
}
}
答案 0 :(得分:1)
调用parser.get()
会强制您的代码等待RssNewsParser
任务完成。通过这样做,您可以有效地暂停应用程序的主线程fetchStories
操作的长度。换句话说,你正在击败使用AsyncTask
的目的。
作为建议,您应该使用Loaders
代替AsyncTasks
将RSS信息恢复到您的活动/片段。它们基本上做同样的事情,但是Loaders将帮助您在旋转之间保持RSS信息,并且更容易将结果返回到您的活动和视图。
答案 1 :(得分:0)
fetchStories()正在主线程中执行,导致所有问题,挂起/进度对话框不可见。
答案 2 :(得分:0)
使用AsyncTask
的错误方法。为什么你一直打电话给'executePendingTransaction()&#39;?什么时候赶时间?无论如何,在分析您的代码后,我建议删除以下代码:
try {
stories=parser.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
请理解&#39; AsyncTask&#39;的工作情况。您必须等待它完成并在onPostExecute()
中执行您想要执行的任何操作。致电&#39;执行()&#39;在下一行手动获取数据是错误的。