0

소켓을 통해 파일을 보내는 앱이 있습니다. 이 과정을 진행하면서 ProgressDialog에서 진행 상황을 보여주고 싶습니다. 앱에서 파일을 완벽하게 전송하지만 대화 상자를 표시 할 수 없습니다.AsyncTask 내에서 스레드를 호출 할 때 ProgressDialog가 나타나지 않습니다.

public class ProgressDialogActivity extends Activity { 

private ProgressDialog downloadDialog = null; 
private String filePath; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    // TODO Auto-generated method stub 
    super.onCreate(savedInstanceState); 

    filePath = getIntent().getExtras().getString("filePath"); 

    downloadDialog = new ProgressDialog(this); 
    Task myTask = new Task(); 
    myTask.execute(0); 
} 

private void showMessage(final String msg) { 
    this.runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      // TODO Auto-generated method stub 
      Toast.makeText(getApplicationContext(), msg, `enter code here`Toast.LENGTH_SHORT).show(); 
     } 
    }); 
} 


private class Task extends AsyncTask<Integer, Integer, Boolean> implements Observer 
{ 
    private Thread t; 

    @Override 
    protected void onPreExecute() { 
     // TODO Auto-generated method stub 
     super.onPreExecute(); 

     downloadDialog.setTitle("SENDING"); 
     downloadDialog.setMessage("................"); 
     downloadDialog.setCancelable(false); 
     downloadDialog.setIndeterminate(false); 
//   downloadDialog.setMax(100); 
     downloadDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
     downloadDialog.show(); 
    } 

    @Override 
    protected Boolean doInBackground(Integer... params) { 
     SendFile send = new SendFile(filePath); 
     downloadDialog.setMax(0); 
     t = new Thread(send); 
     send.registerObserver(this); 
//   try { 
//    Thread.sleep(10000); 
//   } catch (InterruptedException e) { 
//    // TODO Auto-generated catch block 
//    e.printStackTrace(); 
//   } 
     t.start(); 
     return true; 
    } 

    @Override 
    protected void onProgressUpdate(Integer... values) { 
     // TODO Auto-generated method stub 
     super.onProgressUpdate(values); 

     int counter = values[0].intValue(); 
     downloadDialog.setProgress(counter); 
     if(filePath != null) 
     { 
      downloadDialog.setMessage(filePath+"..."); 
     } 
    } 

    @Override 
    public void update(Subject subject) { 
     // TODO Auto-generated method stub 
     if(subject instanceof SendFile) 
     { 
      SendFile e = (SendFile) subject; 
      if(e.getException() != null) 
      { 
       t.interrupt(); 
       showMessage(e.getException()); 
      } else 
      { 
       if(!e.isStarted()) 
       { 
        initializeProgressBar(e.getNumIter()); 
       } else 
       { 
        refreshProgressBar(e.getNumIter()); 
       } 

       if(e.isSent()) 
       { 
        t.interrupt(); 
        showMessage("File sent"); 
       } 
      } 
     } 
    } 

    public void initializeProgressBar(int max){ 
     downloadDialog.setMax(max); 
    } 
    public void refreshProgressBar(int amount){ 
     publishProgress(downloadDialog.getMax()-amount); 
    } 

    @Override 
    protected void onPostExecute(Boolean result) { 
     // TODO Auto-generated method stub 
     super.onPostExecute(result); 

     if(downloadDialog != null) 
     { 
      downloadDialog.dismiss(); 
     } 
        finish(); 
    } 

    @Override 
    protected void onCancelled() { 
     // TODO Auto-generated method stub 
     super.onCancelled(); 
     t.interrupt(); 
     showMessage("TASK CANCELLED"); 
    } 
}; 
} 

SendFile은 파일을 보낼 소켓이 들어있는 클래스입니다.

Thread.Sleep (10000)을 만들 때 그 시간 동안 ProgressDialog를 볼 수 있기 때문에 문제가 AssyncTask 내부의 스레드를 호출하기 때문에 발생한다고 생각합니다. 그러나 문제를 해결하는 방법을 모르겠습니다. 또한

, 내가 디버거를 실행할 때 변수 '카운터'내가 그것을 호출 할 때마다 증가되는 것을 볼 수 있습니다,하지만 난 'downloadDialog.getProgress()' 진행으로 시계를 추가하는 경우 은 항상 0입니다.

+0

확실히 당신이 생각하기에 doInBackground()는 이미 스레드이므로 다른 스레드를 호출 할 필요가 없습니다! – Saqib

+0

아마 표시되지만 너무 빨리 사라져서 보지 못합니다. 'doInBackground'는 이미 쓰레드이므로 다른 쓰레드를 호출 할 필요가 없다. –

답변

0

. 여기서 아무 것도하지 않고 새 스레드를 시작합니다. 이제이 스레드는 작업을 수행하지만 AsyncTask는 완료됩니다. 다른 스레드를 시작한 후에는 아무 일도하지 않기 때문에 ... ProgressDialog가 표시됩니다. 몇 밀리 초 동안 AsyncTask가 끝나고 ProgressDialog가 다시 숨겨집니다. 하지만 작업을 수행하고있는 스레드는 여전히 실행 중이며 AsyncTask 만 완료되었습니다.

솔루션 : AsyncTask를 사용하거나 스레드를 사용하십시오.

+0

나는 스레드에서 진행 상황을 설정해야하기 때문에 스레드를 사용할 수 없다고 생각하지만 메인 스레드가 아닌 다른 스레드에서 UI를 수정할 수는 없습니다. – adryledo

+0

물론 가능합니다. 핸들러를 사용하십시오. 또는 Activity.runOnUIThread(). 하지만,이 경우에는 AsyncTask가 더 좋습니다. – ElDuderino

0

당신은 doinBackground()

예에 publishProgress을 호출해야 넌 doInBackground() 메소드 백그라운드에서 실행되는 AsyncTask를을 만드는

protected String doInBackground(Void... params) { 
     try { 
      int i = 0; 
      Log.i("Thread","1"); 
      Thread.sleep(1000); 
      publishProgress(i++); 
      Log.i("Thread","2"); 
      Thread.sleep(1000); 
      publishProgress(i++); 
      Log.i("Thread","3"); 
      Thread.sleep(1000); 
      Log.i("Thread","4"); 
      Thread.sleep(1000); 
      Log.i("Thread","5"); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     return "done"; 
    }