728x90

작성일자 : 2020.7.14


Retrofit2 라이브러리를 이용하여 데이터 처리하는 걸 테스트하다가 완전 삽질을 한참 했다.

Array로 전체 데이터를 받아서 처리해야 하는데 그렇게 처리하지 않아서 헤메고 있었다.


Retrofit2 기본 개념은 https://link2me.tistory.com/1806 잘 정리되어 있다.


public interface DataCommAPI {
    // POST 방식으로 데이터를 주고 받을 때 넘기는 변수는 Field 라고 해야 한다.
    @FormUrlEncoded
    @POST(Value.AddressData)
    Call<List<Address_Item>> GetAddrData(
            @Field("keyword") String keyword,
            @Field("search") String search
    );
}

@Parcelize
data class Address_Item (
    // 결과를 받을 모델
    var uid: String="",
    var userNM: String="",
    var mobileNO: String?=null,
    var telNO: String?=null,
    var photo: String?=null,
    var checkBoxState: Boolean
): Parcelable


MainActivity.java

public class MainActivity extends AppCompatActivity {
    private final String TAG = this.getClass().getSimpleName();
    Context context;

    private ArrayList<Address_Item> addressItemList = new ArrayList<>(); // 서버에서 가져온 원본 데이터 리스트
    private ArrayList<Address_Item> searchItemList = new ArrayList<>(); // 검색한 데이터 리스트
    private RecyclerView mRecyclerView;
    private RecyclerViewAdapter mAdapter;
    private SearchView editsearch;

    DataCommAPI dataCommAPI;

    static boolean isMSG = false;
    static boolean isAll = false;
    static boolean flag = false;
    static CheckBox checkAll;

    RelativeLayout relative2;
    private BackPressHandler backPressHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = MainActivity.this;
        backPressHandler = new BackPressHandler(this);

        initView();
    }

    private void initView() {
        isMSG = false;
        isAll = false;
        // Relative layout 정의
        relative2 = (RelativeLayout) findViewById(R.id.list_view_relative2);

        mRecyclerView = findViewById(R.id.address_listview);
        mRecyclerView.setHasFixedSize(true);
        LinearLayoutManager manager = new LinearLayoutManager(context);
        DividerItemDecoration decoration = new DividerItemDecoration(context,manager.getOrientation());
        mRecyclerView.addItemDecoration(decoration);
        mRecyclerView.setLayoutManager(manager);

        mAdapter = new RecyclerViewAdapter(context,addressItemList);
        mRecyclerView.setAdapter(mAdapter);

        // Adapter에 추가 데이터를 저장하기 위한 ArrayList
        getServerData(); // 서버 데이터 가져오기
    }

    private void getServerData() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Value.IPADDRESS)
                .addConverterFactory(GsonConverterFactory.create())
                .client(createOkHttpClient())
                .build();

        dataCommAPI = retrofit.create(DataCommAPI.class);

        String keyword = Value.encrypt(Value.URLkey());
        dataCommAPI.GetAddrData(keyword,"").enqueue(new Callback<List<Address_Item>>() {
            @Override
            public void onResponse(Call<List<Address_Item>> call, Response<List<Address_Item>> response) {
                List<Address_Item> result = response.body(); // 전체 데이터

                addressItemList.clear(); // 서버에서 가져온 데이터 초기화
                searchItemList.clear();
               
                for(Address_Item item : result){
                    addressItemList.add(item);
                    searchItemList.add(item);
                }
                runOnUiThread(new Runnable() { // runOnUiThread()를 호출하여 실시간 갱신한다.
                    @Override
                    public void run() {
                        // 갱신된 데이터 내역을 어댑터에 알려줌
                        mAdapter.notifyDataSetChanged();
                    }
                });
            }

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

            }
        });

    }

    private OkHttpClient createOkHttpClient() {
        // 네트워크 통신 로그(서버로 보내는 파라미터 및 받는 파라미터) 보기
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        builder.addInterceptor(interceptor);
        return builder.build();
    }

    public void showAlert(String title, String message) {
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(title);
        builder.setMessage(message)
                .setCancelable(false)
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.dismiss();
                    }
                });
        AlertDialog alert = builder.create();
        alert.show();
    }

    @Override
    public void onBackPressed() {
        backPressHandler.onBackPressed();
    }
}



통신상태가 성공, 실패 여부를 먼저 확인한 다음에

ArrayList 데이터 전체를 출력하는 걸 처리하는 사항

@Parcelize
class AddressResult (
    val status: String,
    val message: String="",
    val addrinfo: List<Address_Item>? = null

): Parcelable
 

public interface RemoteService {
    // POST 방식으로 데이터를 주고 받을 때 넘기는 변수는 Field 라고 해야 한다.
    @FormUrlEncoded
    @POST(Value.AddressData)
    Call<AddressResult> GetAddrData(
            @Field("keyword") String keyword,
            @Field("search") String search
    );
}

private void getServerData() {
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(Value.IPADDRESS)
            .addConverterFactory(GsonConverterFactory.create())
            .client(createOkHttpClient())
            .build();

    dataCommAPI = retrofit.create(RemoteService.class);

    String keyword = Value.encrypt(Value.URLkey());
    dataCommAPI.GetAddrData(keyword,"").enqueue(new Callback<AddressResult>() {
        @Override
        public void onResponse(Call<AddressResult> call, Response<AddressResult> response) {
            if(response.body().getStatus().contains("success")){
                addressItemList.clear(); // 서버에서 가져온 데이터 초기화
                searchItemList.clear();

                for(Address_Item item : response.body().getAddrinfo()){
                    addressItemList.add(item);
                    searchItemList.add(item);
                }
                runOnUiThread(new Runnable() { // runOnUiThread()를 호출하여 실시간 갱신한다.
                    @Override
                    public void run() {
                        // 갱신된 데이터 내역을 어댑터에 알려줌
                        mAdapter.notifyDataSetChanged();
                    }
                });
            } else {
                showAlert(response.body().getStatus(),response.body().getMessage());
            }
        }

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

        }
    });

}


추가 오픈일자 : 2020.9.15일

위 안드로이드 코드와 관련된 PHP 코드

<?php
// 파일을 직접 실행하면 동작되지 않도록 하기 위해서
if(isset($_POST) && $_SERVER['REQUEST_METHOD'] == "POST"){
    @extract($_POST); // POST 전송으로 전달받은 값 처리
    require_once 'config/config.php';
    require_once 'phpclass/dbconnect.php';
    require_once 'phpclass/loginClass.php';
    $c = new LoginClass;

    header("Cache-Control: no-cache, must-revalidate");
    header("Content-type: application/json; charset=UTF-8");

    $R = array(); // 결과 담을 변수 생성
    // 화면에 출력할 칼럼 발췌
    $sql = "select uid,userNM,mobileNO,telNO,photo from Person ";
    if(!empty($search)) {
        $sql .= "where userNM LIKE '%".$search."%' or mobileNO LIKE '%".$search."%'";
    }
    $result = mysqli_query($db,$sql);
    while($row = mysqli_fetch_array($result)) {
        $photo ="null";
        $photo_path = './photos/'.$row['photo'];
        if(file_exists($photo_path)) {
            $photo =$row['photo'];
        }
        array_push($R,  array("uid"=>$row['uid'],"userNM"=>$row['userNM'],"mobileNO"=>$row['mobileNO'],

                                        "telNO"=>$row['telNO'],"photo"=>$photo,"checkBoxState"=>false));
    }

    $status = "success";
    $message = "";
    $addrinfo = $R; // 전체 ArrayList 데이터

    $result = array(
        'status' => $status,
        'message' => $message,
        'addrinfo' => $addrinfo
    );
    echo json_encode($result);

}
?>


728x90
블로그 이미지

Link2Me

,