728x90

이러한 App을 만들고 있다.


웹서버에서 JSON 형태의 "목록" 받음 -> parsing 해서 데이터화 -> gridview에 뿌려줌


별시리 어려울게 없는 구조인데, 구현하는데 애를 먹었다.


바로 이 두 조건 때문이었다.


1. Android의 MainThread에서는 네트워크 기능을 사용할 수 없다. (NetworkOnMainThreadException 발생)


2. Android의 Thread 내부에서는 UI를 조작할 수 없다. (CalledFromWrongThreadException 발생)


이 요소들이 섞이니 아주 the love.


일단 GridView에 들어갈 children은 custom view로 구현 해 두었다. (이러는게 편리)


Fragment 에서는 아래와 같이 작성했다.


final ArrayList items = new ArrayList<>();


class Loader extends AsyncTask<Void, Void, ArrayList<CustomView>> {


protected ArrayList<CustomView> doInBackground(Void... params) {

final ArrayList<CustomView> temp = new ArrayList<>();

JSONArray list = loadList();

for(int i=0; i<list.length(); i++) {

CustomView view = new CustomView(getActivity());

getActivity().runOnUiThread(new Runnable() {

public void run() {

view = controlUI(); //UI와 관련 된 조작은 여기서 한다.

temp.add(view); //임시 Collection에 담아둔다.

synchronized(temp) {

temp.notifyAll();

}

}

});

}

}


protected void onPostExecute(final ArrayList<CustomView> result) {

items.addAll(result); //임시로 담아 둔 것들을 adapter에 설정 된 collection에 모두 넣는다.

customAdapter.notifyDataSetChanged(); //adapter를 갱신한다.

gridView.invalidate(); //GridView를 갱신한다.

}


}


Adapter는 아래와 같다.


public class CustomAdapter extends BaseAdapter {

@Override

public int getCount() {

return items.size();

}


@Override

public Object getItem(int position) {

return items.get(position);

}


@Override

public long getItemId(int position) {

return position;

}


@Override

public View getView(int position, View convertView, ViewGroup parent) {

return items.get(position);

}

}



  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기