更新GridView会触发android.os.NetworkOnMainThreadException

时间:2019-05-19 14:41:44

标签: android gridview android-asynctask

我遇到的问题是,每当我想更新片段中的gridview时,都会出现此错误:

  

android.os.NetworkOnMainThreadException

我要实现什么?

在布局中显示加载的gif,直到片段从后台从firestore加载列表,然后将数据设置到gridview适配器,然后隐藏加载的gif并显示gridview。

我已经尝试了什么?

我试图获取数据并在AsynkTask和后台线程中设置适配器,但是我仍然遇到相同的错误。 (Firestore本身也是异步的)

何时触发错误?

public void updateAdapterView(JSONArray cards) {
    //Error gets triggered here   
    grid.invalidateViews();
    adapter.refresh(cards);
}

片段活动:

  //Set Layout for Fragment
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final FrameLayout view = (FrameLayout) inflater.inflate(R.layout.fragment_exchange, container, false);
    loadinglayout = view.findViewById(R.id.loadinglayout);
    gridlayout = view.findViewById(R.id.gridlayout);

    //first time setting Adapter with empty items
    adapter = new ExchangeListAdapter(getContext(), cards);
    grid = view.findViewById(R.id.grid);
    grid.setAdapter(adapter);
    grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Intent exchangedetail = new Intent(getActivity(), ExchangeDetail.class);
            //exchangedetail.putExtra("item", cardslist[+ position]);
            getActivity().startActivity(exchangedetail);
        }
    });

    return view;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    //get data from firestore
    ((MainActivity) getActivity()).getCardsList(new BaseAppCompatActivity.OnCardsFilledListener() {
        @Override
        public void onCardsFilled(final JSONArray cards) {
            updateAdapterView(cards);
        }

        @Override
        public void onError(Exception taskException) {

        }
    });
}

public void updateAdapterView(JSONArray cards) {
    grid.invalidateViews();
    adapter.refresh(cards);
}

GridView适配器:

public class ExchangeListAdapter extends BaseAdapter {
private Context mContext;
private JSONArray cards;

public ExchangeListAdapter(Context c, JSONArray cards) {
    mContext = c;
    this.cards = cards;
}

@Override
public int getCount() {
    int length = 0;

    if(cards != null) {
      length = cards.length();
    }

    return length;
}

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

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

public void refresh(JSONArray cards)
{
    this.cards = cards;
    notifyDataSetChanged();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View grid;
    LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    if (convertView == null) {
        grid = new View(mContext);
        grid = inflater.inflate(R.layout.item_exchange_list, null);
        ImageView imageView = grid.findViewById(R.id.grid_image);

        URL url = null;
        try {
            url = new URL(cards.getJSONObject(position).getString("thumbnail"));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }

        Bitmap bmp = null;
        try {
            bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }

        imageView.setImageBitmap(bmp);
    } else {
        grid = convertView;
    }

    return grid;
}
}

1 个答案:

答案 0 :(得分:2)

您正在尝试从let task = ORKNavigableOrderedTask(identifier: "first", steps: [dateStep, firstStep,newStep,completion]) //preadicate for "newTask" let predicate = ORKResultPredicate.predicateForTextQuestionResult(with: ORKResultSelector(resultIdentifier: "first"), expectedString: "newStepTask") let rule = ORKPredicateStepNavigationRule( //click firstAnswer jump to newStep resultPredicatesAndDestinationStepIdentifiers: [(predicate, "complete")]) task.setNavigationRule(rule, forTriggerStepIdentifier: "first") return task 方法内的主应用程序线程上的URL加载图像。

将图像加载库(例如Glide或Picasso)添加到项目中。然后,使用该库加载图像。像这样的图书馆可以:

  • 处理占位符图像以获取加载状态
  • 在后台线程上执行网络I / O
  • 缩放图像以适合您的getView(),同时占用更少的内存
  • 如果用户在图像仍在加载时滚动,则进行ImageView回收处理