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

AsyncTask의 콜백에서 ListView의 갱신방법

0 추천

액티비티에서 

서버와 http 통신을 하는 asynctask 를 하나 만들고 asynctask 에 callback 인터페이스를작성합니다

이 callback 인터페이스는 onPostExecute 에서 호출해주며

액티비티는 asynctask의 콜백 인터페이스를 상속받아서 구현합니다

 

즉 http 통신 asynctast에 있는 인터페이스를  액티비티에서 상속받아 원하는 동작을

http통신이 끝난뒤 할 수 있는 형태입니다 

 

http통신결과에 따라 현재 액티비티에 있는 listview를 갱신하는 프로그램을 짜고있는데 

onCreate 에서 는

adapter.addItemTop();
        // 첫 번째 아이템 추가
        adapter.addItemDevice(ContextCompat.getDrawable(this, R.drawable.ref_on),
                "",
                ContextCompat.getDrawable(this, R.drawable.button_power_on2)); ;
        // 두 번째 아이템 추가.
        adapter.addItemDevice(ContextCompat.getDrawable(this, R.drawable.com_on),
                "",
                ContextCompat.getDrawable(this, R.drawable.button_power_on2)) ;
        // 세 번째 아이템 추가.
        adapter.addItemDevice(ContextCompat.getDrawable(this, R.drawable.len_on),
                "",
                ContextCompat.getDrawable(this, R.drawable.button_power_on2)) ;

        adapter.addItemDevice(ContextCompat.getDrawable(this, R.drawable.tv_on),
                "",
                ContextCompat.getDrawable(this, R.drawable.button_power_on2)) ;
        adapter.addItemDevice(ContextCompat.getDrawable(this, R.drawable.ref_on),
                "",
                ContextCompat.getDrawable(this, R.drawable.button_power_on2)) ;


        adapter.addItemBattom();


ListViewItem ss = adapter.getListViewItemList().get(index+1);
ss.setOnoff(ContextCompat.getDrawable(this, R.drawable.button_power_off));

마지막 두줄 코드로 listview의 아이템 갱신이 가능했는데

(리스트뷰에는Top과 device, battom 3종류 view가 있습니다, top과 battom 사이  4개의 device view를 넣어두고 마지막에 두줄로 view가 표시하는 img를 바꾸는 테스트를 했습니다.)

 

아래 콜백에서는 코드는 동작하지만 실질적으로 listview 갱신이 돼지 않습니다.

방법이 없을까요?

public class MainActivity extends AppCompatActivity implements PlugListViewAdapter.PlugListBtnClickListener, APIcall.callback{
    JSONObject jsonObject=null;
    TextView resultTextview=null;
    JSONArray device_list=null;
    PlugListViewAdapter adapter

....

@Override
    public void onTaskDone(String ... params) {  //인터페이스에서 상속받은 객체 onPostExcute 가 호출함
        //Toast.makeText(this,"Http call Done : \n"+resultTextview.getText().toString(), Toast.LENGTH_SHORT).show();
       
ListViewItem ss = adapter.getListViewItemList().get(actionindex);
          ss.setOnoff(ContextCompat.getDrawable(this, R.drawable.button_power_off)); adapter.notifyDataSetChanged();
              
    }

 

 

 

신입 (570 포인트) 님이 2017년 6월 28일 질문
신입님이 2017년 6월 28일 수정

1개의 답변

0 추천
제시된 code만 봐서는 문제가 될만한 부분은 없습니다.

제시된 code말고 제시된 증상만 보았을때는 다음 가능성들이 있어보입니다. (문제상황)

1. onTaskDone() callback이 UI thread가 아닌 thread에서 호출되는 경우

2. adapter.notifyDataSetChanged();를 호출한 adapter가 현재 ListView에 attach가 된 adapter instance가 아닌 경우

3. adapter.getListViewItemList()가 현재 ListView display에 관여하는 data가 아닌 경우
디자이너정 (42,810 포인트) 님이 2017년 6월 28일 답변
읽어주셔서 감사합니다

디버그모드에서 확인한 결과
listview와 adapter는 전역으로 선언해서 참조할 수 있는데
listview에서 getAdapter해서 가져온 것과 기존의 adapter 그리고 listview의 display에 관여하는 객체의 번호 가 일치 했습니다
(디버그모드에서 객체명@number의 number가 일치함)
2,3번의 가능성은 낮아보이고
1번의 가능성이 있는데
이를 확인하기 위해
직접 setOnoff 를 호출하는대신
main.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                actionListViewItem.setOnoff(ContextCompat.getDrawable(MainActivity.this, R.drawable.button_power_off2)); adapter.notifyDataSetChanged();
                            }
                        });
를 사용하는 방법을 사용했지만 listView는 갱신되지 않았습니다.

또 runOnUiThread 를 하지않은 본래상태의0 같은라인에 adapter.addTop()을 실행해 봤는데  listView 의 갱신은 이루어지지 않았으나  addTop은 잘 작동해서 listview 의 추가는 이루어 진 모습을 확인했습니다.

다른어떤 추측이 가능할까요?

(main은 전역 액티비티 객체 이며 onCreate에서 main = this 합니다)
...