마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

파싱후 커스텀리스트... 시간이 오래걸립니다.

0 추천

SAXBuilder를 통한 xml 파싱을해서

SharedPreferences 로 파싱한 값들을 저장합니다.

그 후에 커스텀리스트뷰에 뿌려주는 작업을하는데요.

데이터 2412개를 불러오는데 4분정도 시간이 소요되서..

속도 개선을 해야될것같은데 어떻게 진행을 해야될지 감이안오네요.

db불러오는 속도가 느린가 체크를했더니 db읽어오는 속도는 3초 정도 걸리는데

리스트뷰에 뿌려주는시간이 오래걸리는거같은데...(일단 제일 의심가는 부분입니다.)

속도 개선을 하려면 어떤방법이 있을까요?

protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_accountinfo);
.
.
.
String a1 = pref.getString("count", "");
		Log.d(TAG, a1);
		for (int i = 0; i < Integer.parseInt(a1); i++) {
			adddataList(pref.getString("CUSTNAME" + i, ""),
					pref.getString("CEO" + i, ""),
					pref.getString("TEL" + i, ""),
					pref.getString("ADDRESS" + i, ""),
					pref.getString("EMPNAME" + i, ""),
					pref.getString("CHEMONEY" + i, ""),
					pref.getString("CUSTCODE" + i, ""),
					pref.getString("CUSTNO" + i, ""),
					pref.getString("ZIP" + i, ""),
					pref.getString("FAX" + i, ""),
					pref.getString("EMAIL" + i, ""),
					pref.getString("SLeepCust" + i, ""));

		}
.
.
.
}


// 커스텀리스트
	private void adddataList(String custname, String ceo, String tel,
			String ADRESS, String EMPNAME, String CHEMONEY, String CUSTCODE,
			String CUSTNO, String ZIP, String FAX, String EMAIL,
			String SLeepCust) {
		listdata.add(new EachList_2(custname, ceo, tel, ADRESS, EMPNAME,
				CHEMONEY, CUSTCODE, CUSTNO, ZIP, FAX, EMAIL, SLeepCust));
		setdataList();
	}

	

	// 커스텀리스트
	private void setdataList() {
		list.setAdapter(li);
	}
.
.
.
// 커스텀리스뷰 Adapter
	public class listdata_2 extends BaseAdapter {
		private Context context;
		private ArrayList<EachList_2> datalist;
		private int layout;
		private LayoutInflater inflater;
		private clsUtil clsUtil;
		private clsCustomDialog clsDlg;

		public listdata_2(Context context, int layout,
				ArrayList<EachList_2> listlist) {

			this.context = context;
			this.layout = layout;
			this.datalist = listlist;
			inflater = (LayoutInflater) context
					.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		}

		@Override
		public int getCount() {
			return datalist.size();
		}

		@Override
		public Object getItem(int position) {
			return datalist.get(position);

		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		public String getADRESS(int position) {
			return datalist.get(position).ADRESS;
		}

		public String getEMPNAME(int position) {
			return datalist.get(position).EMPNAME;
		}

		public String getCHEMONEY(int position) {
			return datalist.get(position).CHEMONEY;
		}

		public String getcustname(int position) {
			return datalist.get(position).custname;
		}

		public String getceo(int position) {
			return datalist.get(position).ceo;
		}

		public String gettel(int position) {
			return datalist.get(position).tel;
		}

		public String getCUSTCODE(int position) {
			return datalist.get(position).CUSTCODE;
		}

		public String getCUSTNO(int position) {
			return datalist.get(position).CUSTNO;
		}

		public String getZIP(int position) {
			return datalist.get(position).ZIP;
		}

		public String getFAX(int position) {
			return datalist.get(position).FAX;
		}

		public String getEMAIL(int position) {
			return datalist.get(position).EMAIL;
		}

		public String getSLeepCust(int position) {
			return datalist.get(position).SLeepCust;
		}

		@Override
		public View getView(final int position, View convertView,
				ViewGroup parent) {
			if (convertView == null) {
				convertView = inflater.inflate(layout, parent, false);
			}

			TextView txtcustname = (TextView) convertView
					.findViewById(R.id.txtcustname);
			TextView txtceo = (TextView) convertView.findViewById(R.id.txtceo);
			TextView txttel = (TextView) convertView.findViewById(R.id.txttel);

			// 리스트에 뿌리기
			txtcustname.setText(datalist.get(position).custname);
			txtceo.setText(datalist.get(position).ceo);
			txttel.setText(datalist.get(position).tel);
.
.
.
}

 

아잉훗 (570 포인트) 님이 2015년 10월 8일 질문
아잉훗님이 2015년 10월 8일 수정

2개의 답변

0 추천
 
채택된 답변
리스트를 Adater에 바인딩 하는 부분하고, Adapter 코드 전체를 첨부해 주시면 확인하는데 도움이 됩니다. 코드 없이 이런 질문으로는 정확한 답변을 드리기 어렵습니다.
mcsong (44,040 포인트) 님이 2015년 10월 8일 답변
아잉훗님이 2015년 10월 12일 채택됨
리스트뷰 부분 코드만 첨부했습니다..
전체코드를 올릴수없어서 일부분만 첨부했네요..
첨부해 주신 소스만으로는 정말 느릴 만한 부분은 없어 보이는데요.. 정말 느린 포인트를 못 찾으신다면 프로파일링을 해 보는 것을 추천드립니다.
테스트를 해보니
xml 파싱 > SharedPreferences (데이터저장 2412 * 12) > listview
sharedpreferences 부분에서 많이 느린데...
이부분은 방법이없을까요..??
아무래도 SharedPreferences 에서 3만개 데이터를 밀어넣는데서 시간이 오래걸리는것같습니다..ㅠㅠ
애초에 sharedPreference는 대용량 데이터 관리에 적합하지 않습니다.
저정도의 대용량의 데이터를 관리하실거면, sqlLite나 데이터 관련 라이브러리를 쓰시는 게 맞습니다.

sharedPreference 작업하는 곳을 쓰레드로 돌리면 속도는 한결 나아지겠지만, 그게 제대로된 방법은 아닐것 같네요.
xml 및 파싱 : xml 자체가 무겁고 파싱이 느리기 때문에 요즘은 json 포맷이나 성능 이슈가 많은 앱에서는 직렬화 라이브러리를 많이 사용하고 있습니다.

SharedPreference : 위에 분이 말씀하신 것처럼 구조화된 데이터 관리에는 적합하지 않습니다.
단순 텍스트 저장이면 문제가 없지만, 구조화된 데이터를 사용하는데는 DB를 사용하세요.
개인적으로 sqlite보다는 Realm을 추천드립니다.

ViewHolder 패턴 : 아래 분이 말씀하셨는데 꼭 사용하시는 게 좋습니다.
데이터 부분 바인딩 : 100개 바인딩하고 맨 아래 왔을때 다시 100개 추가 바인딩하는 형태인데..
한꺼번에 2000개와 같이 너무 많은 데이터를 사용하게 되면 메모리를 너무 많이 점유하게 되므로 점진적으로 늘려주는 것도 좋습니다.
0 추천
일단 해당 코드에서 눈에 뛰는 문제점은 setdataList 메소드가 addListData 메소드 마지막에 호출되는데

addListData  메소드는 저장한 몇전개의 데이터를 파싱해서 그 인덱스만큼 해주는 거겠죠?

그럼 그 add가 다 끝나고 setdataList 한번만 불려지면 될 것 같은데 각 인덱스마다 호출이 잘 못 되고 있습니다.

 

그리고 getView 역시 뿌려주는 방법이 몇가지 방법이 있는데 그중 가장 느린 방법으로 뿌려주는 방법입니다.

위와 같이 convertView가 널이 아니라면이라는 구문이 없으면 의미가 없으므로 뷰 홀더 패턴 을 잘 적용해보시기 바랍니다.

그 정도 수정을 하고 다시 돌려보시면 어떨까 하네요.

그리고 데이터는 빨리 읽어 왔다고 한다면 리스트뷰에 몇천개를 한번에 빠르게 표시하는건 좋은 방법이 아니므로

리스트 더보기 방식을 검색해보셔서 리스트 포지션이 가장 아래에 내려갔을테 추가 데이터를 표현하는 방법이 어떨까요
쭈쭈총각 (17,750 포인트) 님이 2015년 10월 8일 답변
...