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

progresssdialog 사용하려는데 의도한 실행 순서대로 실행되지 않습니다.

0 추천

progressdialog 이용해서

버튼 클릭->progressdialog.show()->사용자 정의 함수->progressdialog.dismiss() 순으로 실행하려고 했는데

밑에 코드를 실행시켜보면

버튼 클릭->사용자 정의 함수->progressdialog.show()->progressdialog.dismiss() 순으로 실행되어서 progressdialog가 실행되지 않는 것 처럼 보입니다. dismiss()를 주석처리하고 progressdialog.setCancelable(true)로 확인하여 알아냈습니다.

thread를 이용하지 않고 의도한 순서 대로 실행시키려면 어떻게 해야하나요? 

질문 관련 코드만 뽑아서 밑에 첨부합니다...

public class Fragment2 extends Fragment {
    private Button startBtn;

    //progress dialog
    ProgressDialog progressDialog, progressDialog2;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.photo1, container, false);

        startBtn = view.findViewById(R.id.startBtn);

        progressDialog2 = new ProgressDialog(getActivity());
        progressDialog2.setMessage("Learning...");
        progressDialog2.setCancelable(true);
        progressDialog2.setProgressStyle(android.R.style.Widget_ProgressBar_Horizontal);

        startBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                progressDialog2.show();
                start(v);
                startBtn.setEnabled(false);
            }
        });

        return view;
    }

    public void start(View v) {

        //progressdialog.show() 동안 해야 할 작업들...

        try { ... } catch(Exception e){ ... } 

        //progressdialog2.dismiss();
    }

(+ 첨부한 파일에서 progressdialog를 두번 사용하려고 하는데 progressdialog라고 이름 붙인 것은 잘 실행됩니다. 그런데 dismiss() 명령어를 

    progressDialog.show();

    SetImageView(); //직접 정의한 함수

    progressDialog.dismiss();

순으로 넣으면 setimageview()->show()->dismiss() 순으로 실행되고 

setimageview()라고 정의한 함수 안에서도 setimageview안에 .addListener를 사용하는데 이 리스너 안에 dismiss()를 넣어야 의도한 순서대로 실행되고

 setimageview안+리스너밖에 dismiss()를 넣으면 setimageview()->show()->dismiss() 순입니다. 

 

대체 왜 코드 입력한 순서대로 안되는 거죠... 인터넷에서 예제 찾아보면 꼭 thread 사용해야만 하는건 아닌것 같았고 thread 사용하려고 했을 때도 여전히 순서 문제에 다른 문제들이 추가적으로 발생해서 thread는 되도록 사용하고 싶지 않습니다....)

쓰레기통612호 (150 포인트) 님이 2021년 11월 6일 질문

1개의 답변

0 추천
 
채택된 답변

쓰레드는 비동기적으로 동작하므로 쓰레드 밖의 코드는 쓰레드가 끝날 때까지 대기하지 않으므로, 질문하신 것과 같은 증상이 발생합니다.

Thread를 사용하고 안하고는 Thread 안에서 어떤 작업을 처리하시느냐에 딸라 달라집니다. 모발일 앱에는 두가지 쓰레드가 존재합니다. (그냥 간단한 버전으로 설명할게요.)

1. UI thread(= Main thread) - 화면 업데이트.

2. Background thread(= Worker thread) - 그 외의 비동기 작업.

따라서 비동기 작업이 필요한 파일 읽기 쓰기, 데이터베이스 처리, 네트워킹 등을 백그라운드 쓰레드를 이용하시는 게 원칙입니다. 이걸 님이 원하는 동기화시키는 방식들이 지원되구요. Callback, observer, RxJava, Coroutine 등등 여러가지 기법과 라이브러리들이 존재합니다.

따라서 바른 해결방법은 Thread과 필요한지 아닌지 먼저 확인하시고, 사용해야 하는 경우라면 동기화할 수 있는 테크닉을 하나 사용하시면 됩니다. 어차피 모발 앱을 구현하는데에서 비동기처리는 아주 많이 접하게 되는 항목이니 해결하고 넘어가시는게 좋아요.

가장 간단한 구현은, thread 안에서 UI를 제어하면 됩니다. 

public void start(View v) {

         progressdialog.show() 동안 해야 할 작업들...

        try { 
          ..

            //  쓰레드 "내부" 에서 아랫처럼 UI에 접근 함. runOnUiThread 는 핸재 백그라운드 쓰레드 안에 있기 때문에, 
            // UI에 접근하기 위해서 UI thread로 전환하는 역할을 함.(위에서 말씀드린대로, UI threa가 화면 업데이트를 하기 때문)
            runOnUiThread(() -> {
                  progressdialog.dismiss();
            });


       } catch(Exception e){ ... } 
           progressdialog.dismiss();
      }

 

spark (139,480 포인트) 님이 2021년 11월 6일 답변
쓰레기통612호님이 2021년 11월 13일 채택됨
...