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

안드로이드스튜디오 스레드 변수 저장

0 추천

A클래스에 있는 Test메서드를 통해 객체 배열을 리턴 받고자 합니다.

(A클래스)

private ArrayList<Student> students;
public ArrayList<Student> Test() {
    ServerThread thread = new ServerThread();
    thread.start();
    Log.e("리스트 확인", students.toString());
    return students;
}

(↓스레드 코드)

students = new ArrayList<Student>();
//Student 객체 배열에 저장
for(int i=0; i<student_data.length; i++) {
    Student student = new Student();
    //중략
    Log.e("학생 객체", student.toString());

    students.add(student);
}
Log.e("Thread List", students.get(0).toString());

스레드에서는 students가 잘 저장되어있는게 확인되는데

Test()에서의 로그에서는 Null로 표시됩니다.

이유를 모르겠습니다 ㅜㅜ

안촙 1 (280 포인트) 님이 2022년 12월 3일 질문

1개의 답변

+1 추천
 
채택된 답변

Thread가 비동기인 것만 이해하셔도 문제가 왜 발생하는지 쉽게 짐작이 가능합니다.

students가 초기화 되는 코드가 Thread 안에 있기 때문에, 그렇게 될 수 있겠죠.

아래처럼 초기화 코드를 옮기시면 널이 발생하지 않겠죠.

public ArrayList<Student> Test() {
    students = new ArrayList<Student>();  //<-- 초기화 먼저
    ...
    return students;
}

하지만 여전히 비동기방식으로 동작을 하므로 위와 같이 하더라고 students는 빈 리스트가 될 가능성이 높습니다. 따라서 Test()메소드는 잘못 작성된 메소라고 볼 수 있습니다. 쓰레드는 언제 끝날 지 알 수 없기 때문에, 쓰레드 작업이 끝날 때 필요한 결과를 받으려면 콜백이라는 방법을 사용하셔야 해요.

public interface Listener {
    void onStudentsFetched(List<Student> students)
}

// 쓰레드 코드
public void fetchStudents(Listener listener) {
      
     List<Student> result = new ArrayList<Student>();
 
     for(int i=0; i<student_data.length; i++) {
           Student student = new Student();
          //중략
           Log.e("학생 객체", student.toString());

         result.add(student);
      }

       if (listener != null) listener.onStudentsFetched(result);
}



private Listener listener = new Listener {
    @Override
    public void onStudentsFetched(List<Student> students) {
          // Do something
    }
}

fetchStudents(listener);

 

spark (227,470 포인트) 님이 2022년 12월 3일 답변
안촙 1님이 2022년 12월 4일 채택됨
...