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

리싸이클러뷰 리스트 데이터 가져오기 실패

0 추천

안녕하세요. 안드로이드 스튜디오 자바 코드를 이용해 리스트 페이지를 만들고자 합니다. 서버에서 데이터 리스트를 가져와 리싸이클러뷰로 히스토리 페이지를 만드는 작업을 진행중인데, 데이터 파싱 문제인지 모르겠으나 리스트가 제대로 출력이 되지 않습니다. 사소한 문제인듯 싶은데 초보자라 그런지 문제를 어디서 어떻게 찾아야 하는지 모르겠네요. 백엔드 쪽 JavaScript 코드 문제인가 싶어 여러가지 해봤으나 해결이 되질않아 이렇게 도움을 요청해봅니다. 앱 실행 후 app log를 확인해보면 아래처럼 주소+랜덤한 String이 데이터 대신 이렇게 뜹니다.

 

아래는 제 자바스크립트 코드와 안드로이드 스튜디오 자바 코드입니다.

sql.ts:

app.get('/ring/event', function(req, res) {
        var sql = 'SELECT * FROM defaultdb.Event_history';
        connection.query(sql, function (err, result) {
                var resultCode = 404;
                var message = 'Error!';
                if (err) {
                        console.log(err);
                } else {
                        resultCode = 200;
                        message = 'Success!';
                }
                res.json({
                        'code':resultCode,
                        'message':message,
                        'result':result
                });
        });
});

 

HistoryData.java

public class HistoryData {

    @SerializedName("eventID")
    private int eventID;

    @SerializedName("sensorID")
    private String sensorID;

    @SerializedName("sensorName")
    private String sensorName;

    @SerializedName("eventType")
    private String eventType;

    @SerializedName("eventDate")
    private String eventDate;

    @SerializedName("eventTime")
    private String eventTime;

    @SerializedName("userID")
    private int userID;


    public HistoryData(int eventID, String sensorID, String sensorName, String eventType, String eventDate, String eventTime, int userID) {
        this.eventID = eventID;
        this.sensorID = sensorID;
        this.sensorName = sensorName;
        this.eventType = eventType;
        this.eventDate = eventDate;
        this.eventTime = eventTime;
        this.userID = userID;
    }

    public String getSensorName() {
        return sensorName;
    }

    public void setSensorName(String sensorName) {
        this.sensorName = sensorName;
    }

    public String getEventDate() {
        return eventDate;
    }

    public void setEventDate(String eventDate) {
        this.eventDate = eventDate;
    }

    public String getEventTime() {
        return eventTime;
    }

    public void setEventTime(String eventTime){
        this.eventTime = eventTime;
    }

}

 

HistoryResponse.java

public class HistoryResponse {
    @SerializedName("code")
    public int code;

    @SerializedName("message")
    public String message;

    @SerializedName("result")
    public List<HistoryData> result;

    @Override
    public String toString() {

        return "HistoryResponse{" + "result=" + result +'}';
    }

}

 

ServiceApi.java:

public interface ServiceApi {
    @POST("/user/login")
    Call<LoginResponse> userLogin(@Body LoginData data);

    @POST("/user/join")
    Call<JoinResponse> userJoin(@Body JoinData data);

    @GET("/ring/event")
    Call<HistoryResponse> getData();
}

 

RecyclerAdapter.java:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder>{

    private Context c;
    private List<HistoryData> dataList;

    public RecyclerAdapter(Context c, List<HistoryData> dataList) {
        this.c = c;
        this.dataList = dataList;
    }

    @NonNull
    @Override
    public RecyclerAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(c).inflate(R.layout.activity_history, parent, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerAdapter.MyViewHolder holder, int position) {

        holder.name.setText("" + dataList.get(position).getSensorName());
        holder.time.setText("" + dataList.get(position).getEventTime());
        holder.date.setText("" + dataList.get(position).getEventDate());

    }

    @Override
    public int getItemCount() {
        return (dataList == null) ? 0 : dataList.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {

        TextView name;
        TextView time;
        TextView date;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);

            name = (TextView)itemView.findViewById(R.id.sensorName);
            time = (TextView)itemView.findViewById(R.id.eventType);
            date = (TextView)itemView.findViewById(R.id.eventDate);

        }
    }
}

 

HistoryActivity.java:

public class HistoryActivity extends AppCompatActivity {

    HistoryResponse dataList;

    List<HistoryData> dataInfo;

    private RecyclerView recyclerView;
    private RecyclerAdapter recyclerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.recycler_view);

        dataInfo = new ArrayList<>();
        recyclerView = findViewById(R.id.recyclerView);

        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        ServiceApi apiInterface = RetrofitClient.getClient().create(ServiceApi.class);

        Call<HistoryResponse> call = apiInterface.getData();

        recyclerAdapter = new RecyclerAdapter(getApplicationContext(), null);
        recyclerView.setAdapter(recyclerAdapter);

        call.enqueue(new Callback<HistoryResponse>() {
            @Override
            public void onResponse(Call<HistoryResponse> call, Response<HistoryResponse> response) {

                dataList = response.body();

                Log.d("HistoryActivity", dataList.toString());

                dataInfo = dataList.result;

                recyclerAdapter = new RecyclerAdapter(getApplicationContext(), dataInfo);
                recyclerView.setAdapter(recyclerAdapter);
            }

            @Override
            public void onFailure(Call<HistoryResponse> call, Throwable t) {

                Log.d("HistoryActivity", t.toString());
            }
        });
    }

}

 

응애코딩 (160 포인트) 님이 2022년 4월 14일 질문
응애코딩님이 2022년 4월 14일 수정
recyclerAdapter = new RecyclerAdapter(getApplicationContext(), null);
위처럼, 액티비티 안에서만 사용하는 뷰에 ApplicaitonContext를 넘기시면 안됩니다. Applcation의 라이프사이클이 Activity보다 길기 때문에, 위처럼 넘기시면 "해당 액비티티가 종료되더도,  recyclerAdapter를 사용하겠다"는 의미로 해석될 수 있습니다. 제일 좋은 방법은
RecyclerView에는 Context자체를 넘기지 않는 겁니다. Context는 외부에서만 사용하세요. 꼭 사용하시겠다면 getApplicationContext()대신 액티비티의 Context를 넘기세요.

어댑터에서는 아랫처럼 사용하셔도 됩니다.
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_history, parent, false);

1개의 답변

+1 추천
 
채택된 답변

로그에 찍힌 건 클래스의 인스턴스를 출력한 겁니다. 이유는 toString()메소드를 제공하지 않으셨기 때문에 자바가 Object의 기본구현된 코드를 사용한 겁니다. 해당 클래스에서 toString()이라고 입력하시면 안드로이드 스튜디오가 해당 메소드를 오버라이드 할 건지 힌트를 줄 겁니다. 해당 메뉴를 누르면 클래스를 필드값을 보여줄 수 있는 코드를 완성해 줍니다. 아니면, 직접 toString()을 오버라이드 하시면 됩니다.

@Override
    public String toString() {
        return "HistoryData (" +
        "eventID:" + eventID +
       //다른 필드 추가
        ")";
    }

 

브레이크 포인트를 찍어서 디버깅을 해보시면 굳이 출력을 하지 않아도 값 확인이 가능합니다. 구글 찾아보시면 어떻게 디버깅을 하는지 잘 나옵니다.

spark (227,510 포인트) 님이 2022년 4월 14일 답변
응애코딩님이 2022년 4월 15일 채택됨
...