2011-09-05 1 views
2

다운로드 진행 상황을 보여주는 스 니펫을 온라인에서 찾았습니다. 내가지고있어 오류가 내 목표는 완료 할 때 전화가 다음 파일을 다운로드하고있는 chaptermenu 의도Android - 기본 다운로드 진행률 텍스트

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.URL; 

import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.os.Environment; 
import android.widget.TextView; 

public class CheckDownload extends Activity { 

/** Called when the activity is first created. */ 
@Override 
protected void onCreate(Bundle SavedInstanceState) { 
    // TODO Auto-generated method stub 
    super.onCreate(SavedInstanceState); 
    setContentView(R.layout.downloadscreen); 
    Thread timer = new Thread() { 
     public void run() { 
      try { 
       // set the download URL, a url that points to a file on the 
       // internet 
       // this is the file to be downloaded 
       URL url = new URL(
         "http://www.android.com/media/wallpaper/gif/android_logo.gif"); 

       // create the new connection 
       HttpURLConnection urlConnection = (HttpURLConnection) url 
         .openConnection(); 

       // set up some things on the connection 
       urlConnection.setRequestMethod("GET"); 
       urlConnection.setDoOutput(true); 

       // and connect! 
       urlConnection.connect(); 

       // set the path where we want to save the file 
       // in this case, going to save it on the root directory of 
       // the 
       // sd card. 
       File SDCardRoot = Environment.getExternalStorageDirectory(); 
       // create a new file, specifying the path, and the filename 
       // which we want to save the file as. 
       File file = new File(SDCardRoot, "android_logo.gif"); 

       // this will be used to write the downloaded data into the 
       // file we created 
       FileOutputStream fileOutput = new FileOutputStream(file); 

       // this will be used in reading the data from the internet 
       InputStream inputStream = urlConnection.getInputStream(); 

       // this is the total size of the file 
       int totalSize = urlConnection.getContentLength(); 
       // variable to store total downloaded bytes 
       int downloadedSize = 0; 

       // create a buffer... 
       byte[] buffer = new byte[1024]; 
       int bufferLength = 0; // used to store a temporary size of 
             // the buffer 

       // now, read through the input buffer and write the contents 
       // to the file 
       while ((bufferLength = inputStream.read(buffer)) > 0) { 
        // add the data in the buffer to the file in the file 
        // output stream (the file on the sd card 
        fileOutput.write(buffer, 0, bufferLength); 
        // add up the size so we know how much is downloaded 
        downloadedSize += bufferLength; 
        // this is where you would do something to report the 
        // prgress, like this maybe 
        updateProgress(downloadedSize, totalSize); 

       } 
       // close the output stream when done 
       fileOutput.close(); 

       // catch some possible errors... 
      } catch (MalformedURLException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } finally { 
       Intent chapterMenuIntentObject = new Intent(
         "com.blah.blah.CHAPTERMENU"); 
       startActivity(chapterMenuIntentObject); 
      } 
     } 

    }; 
    timer.start(); 
} 

public void updateProgress(int downloadedSize, int totalSize) { 
    int percentage = downloadedSize/totalSize * 100; 
    String stringy = "Download Progress: " + percentage + "%"; 
    TextView textytext = (TextView) findViewById(R.id.downloadscreentextview); 
    textytext.setText(stringy); 
} 

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

} 

답변

2

당신은 노동자 (또는 백그라운드 스레드)에서 진행 상황을 업데이트하려고로 전환하는 것입니다 android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.입니다 그것은 당신의 견해에 대한 언급을 얻지 못합니다. 그것은 UI 스레드에서 수행되어야합니다.
AsynTask를 사용해보십시오. 스레드를 사용하면 더 쉽게 작업 할 수 있습니다.
http://developer.android.com/reference/android/os/AsyncTask.html

또는

정상적인 스레드를 고수하려는 경우

, 확인이 코드,
http://huuah.com/android-progress-bar-and-thread-updating/
당신의 ProgressBar에 메시지를 보낼에 messageHandler를 사용해야하고 업데이트 할 수 있습니다.

0

현재 실행중인 스레드가 GUI를 업데이트 할 수 없으므로 이러한 유형의 오류가 발생해야합니다. gui를 업데이트하려면 Android의 Handler 개념을 이해해야합니다. Handler을 읽으십시오. 안드로이드에.

나는 u는 다음과 같이 코드를 변경해야한다고 생각 : -이 작업을 수행하는

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.URL; 

import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.os.Environment; 
import android.os.Handler; 
import android.os.Message; 
import android.widget.TextView; 

public class CheckDownload extends Activity { 

private TextView textytext; 
private int totalSize; 
private int downloadedSize = 0; 
private TimerThread timer = new TimerThread(); 

/** Called when the activity is first created. */ 
@Override 
protected void onCreate(Bundle SavedInstanceState) { 
    // TODO Auto-generated method stub 
    super.onCreate(SavedInstanceState); 
    setContentView(R.layout.downloadscreen); 

    timer.start(); 
} 

public void updateProgress(int downloadedSize, int totalSize) { 
    int percentage = downloadedSize/totalSize * 100; 
    String stringy = "Download Progress: " + percentage + "%"; 
    TextView textytext = (TextView) findViewById(R.id.downloadscreentextview); 
    textytext.setText(stringy); 
} 

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

private class TimerThread extends Thread { 

    @Override 
    public void run() { 
     try { 
      // set the download URL, a url that points to a file on the 
      // internet 
      // this is the file to be downloaded 
      URL url = new URL(
        "http://www.android.com/media/wallpaper/gif/android_logo.gif"); 

      // create the new connection 
      HttpURLConnection urlConnection = (HttpURLConnection) url 
        .openConnection(); 

      // set up some things on the connection 
      urlConnection.setRequestMethod("GET"); 
      urlConnection.setDoOutput(true); 

      // and connect! 
      urlConnection.connect(); 

      // set the path where we want to save the file 
      // in this case, going to save it on the root directory of 
      // the 
      // sd card. 
      File SDCardRoot = Environment.getExternalStorageDirectory(); 
      // create a new file, specifying the path, and the filename 
      // which we want to save the file as. 
      File file = new File(SDCardRoot, "android_logo.gif"); 

      // this will be used to write the downloaded data into the 
      // file we created 
      FileOutputStream fileOutput = new FileOutputStream(file); 

      // this will be used in reading the data from the internet 
      InputStream inputStream = urlConnection.getInputStream(); 

      // this is the total size of the file 
      totalSize = urlConnection.getContentLength(); 
      // variable to store total downloaded bytes 
      downloadedSize = 0; 

      // create a buffer... 
      byte[] buffer = new byte[1024]; 
      int bufferLength = 0; // used to store a temporary size of 
            // the buffer 

      // now, read through the input buffer and write the contents 
      // to the file 
      while ((bufferLength = inputStream.read(buffer)) > 0) { 
       // add the data in the buffer to the file in the file 
       // output stream (the file on the sd card 
       fileOutput.write(buffer, 0, bufferLength); 
       // add up the size so we know how much is downloaded 
       downloadedSize += bufferLength; 
       // this is where you would do something to report the 
       // prgress, like this maybe 
       handler.sendEmptyMessage(0); 
      } 
      // close the output stream when done 
      fileOutput.close(); 

      // catch some possible errors... 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      handler.sendEmptyMessage(1); 
     } 
    } 
} 

private Handler handler = new Handler() { 
    @Override 
    public void handleMessage(Message msg) { 

     switch (msg.what) { 

     case 0: 
      updateProgress(downloadedSize, totalSize); 
      break; 
     case 1: 
      Intent chapterMenuIntentObject = new Intent(
        "com.blah.blah.CHAPTERMENU"); 
      startActivity(chapterMenuIntentObject); 
     } 

    } 
}; 
} 
4

하나 쉬운 방법은 runOnUIThread (Runnable를) 함수를 사용하는 것입니다. 이것은 UI 업데이트를위한 Activity 클래스의 함수입니다. UI 스레드와 통신하기 위해 핸들러/메시지를 만드는 것보다 더 편리하게 사용할 수 있습니다. 코드를 (아직 테스트하지 않았습니다.)

public void updateProgress(int downloadedSize, int totalSize) { 
runOnUiThread(new Runnable() { 
    public void run() { 
     int percentage = downloadedSize/totalSize * 100; 
     String stringy = "Download Progress: " + percentage + "%"; 
    TextView textytext = (TextView) findViewById(R.id.downloadscreentextview); 
    textytext.setText(stringy); 
}}); 
} 

오류가 있으면 알려주십시오.

+0

매력처럼 작동했습니다! 정말 고마워! 어떻게하면 sdcard에 폴더를 만들고이 코드를 사용하여 전체 진행률을 계산할 여러 파일을 다운로드 할 수 있습니까? – BretzelPretzel

+0

나는 당신의 질문을 정말로 얻지 못한다. 난 당신이 백그라운드 스레드가 SDCard I/O를하고 runOnUiThread를 사용하여 작업이 완료되는 UI 스레드를 업데이트 할 수 있다고 생각합니다. 내가 너의 요점을 잘못 이해하면 알려줘. –

+0

죄송합니다. 나는 바깥 질문을했습니다. 어리석은 질문입니다. 내가 발견 한 한 가지 문제는 무엇이 원인인지 알 수 없지만 귀하의 방법을 사용할 때 진도 업데이터는 0에서 100 %로 ..... 어떤 아이디어로 바뀌 었습니까? – BretzelPretzel