본문 바로가기

개발 이야기

Android | 앱 화면 구성 중에 DB에서 Data 읽어올때 코딩 가이드

320x100

 

안드로이드 앱 개발 시 onCreate() 에서 DB를 UI Thread에서 읽어온 후 화면구성하는 코드가 많아 Work Thread에서 데이터 가공 및 화면갱신하는 코드 기초가이드를 작성해 보겠습니다.

 

1. Handler 와 Threa 를 이용한 코딩

 

Thread를 통해 DB 가져오는 작업을 한 후에 실제 ListView adapter 갱신 부는 Handler 를 통해 UI Thread 상 업데이트를 실행하는 코드로 사용자가 back-key 를 입력해서 강제 종료 시 해당 DB가져오는 쓰레드도 종료하게 처리함.

 

public class MyFragment extends Fragment {

    private ListView listView;
    private MyAdapter adapter;
    private Handler handler;
    private Thread thread;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_layout, container, false);
        listView = (ListView) view.findViewById(R.id.my_list_view);
        adapter = new MyAdapter();
        listView.setAdapter(adapter);

        handler = new Handler();

        // 데이터 로드 작업 실행
        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                final List<MyData> data = loadDataFromDb();

                if (getActivity() != null) {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            adapter.setData(data);
                        }
                    });
                }
            }
        });
        thread.start();

        return view;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (thread != null) {
            thread.interrupt();
        }
    }

    private List<MyData> loadDataFromDb() {
        // 데이터를 DB에서 로드하는 코드
    }
}

 

 

2. WorkManager 를 이용한 코딩

 

Asynctask 대용으로 추천하는 WorkManager를 이용하여 앱 기초 구조를 코딩했습니다.

결과는 위와 같습니다.

 

public class MyFragment extends Fragment {

    private ListView listView;
    private MyAdapter adapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_layout, container, false);
        listView = (ListView) view.findViewById(R.id.my_list_view);
        adapter = new MyAdapter();
        listView.setAdapter(adapter);

        // 데이터 로드 작업 실행
        OneTimeWorkRequest loadDataRequest = new OneTimeWorkRequest.Builder(LoadDataWorker.class).build();
        WorkManager.getInstance(requireContext()).enqueue(loadDataRequest);

        // 작업 상태 관찰
        WorkManager.getInstance(requireContext()).getWorkInfoByIdLiveData(loadDataRequest.getId())
                .observe(getViewLifecycleOwner(), new Observer<WorkInfo>() {
                    @Override
                    public void onChanged(@Nullable WorkInfo workInfo) {
                        if (workInfo != null && workInfo.getState() == WorkInfo.State.SUCCEEDED) {
                            // 작업이 성공적으로 완료된 경우, 데이터를 가져와서 adapter에 넣음
                            List<MyData> data = workInfo.getOutputData().getKeyValueMap().get("data");
                            adapter.setData(data);
                        }
                    }
                });

        return view;
    }

    public static class LoadDataWorker extends Worker {

        public LoadDataWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
            super(context, workerParams);
        }

        @NonNull
        @Override
        public Result doWork() {
            List<MyData> data = loadDataFromDb();

            // 데이터를 WorkInfo로 전달
            Data outputData = new Data.Builder()
                    .putStringArray("data", data)
                    .build();

            return Result.success(outputData);
        }

        private static List<MyData> loadDataFromDb() {
            // 데이터를 DB에서 로드하는 코드
        }
    }
}

 

 

가급적이면 UI Thead상에서 DB를 읽어와서 RecycyerView, ListView 의 Adapter를 갱신하는 일은 자제해 주시길~

 

 

반응형