2011-06-24 50 views
1

この質問を以前に聞いたことがありますが、回答が見つからず、同じ問題を日中に見ています。glumsetProgressによって更新された場合、Android ProgressBarは更新されません

長時間のダウンロードプロセス中に更新したい3つのプログレスバーがある画面があります。何を試しても、プログレスバーを更新することはできません。

完全なソースがhereです:

マイFileDownloadManagerクラス:

package org.touchandgo.speak; 

import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.FileReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.ArrayList; 

import android.app.Activity; 
import android.app.AlertDialog; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.net.ConnectivityManager; 
import android.os.Bundle; 
import android.os.Environment; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.CheckBox; 
import android.widget.ProgressBar; 
import android.widget.TextView; 

public class FileDownloadManager extends Activity 
{ 
    public static final String FILE_MANIFEST = "http://dl.dropbox.com/u/25690498/TouchAndGoSpeakImages/TouchAndGoSpeak_Download.manifest"; 
    public static final String LOCAL_FILE_MANIFEST = "TouchAndGoSpeak_Download.manifest"; 
    public static final String LOGid = "TouchAndGoSpeak"; 

    private String msBaseFolder = ""; 
    private TextView tvCurrent; 

    public void onCreate(Bundle icicle) 
    { 
     super.onCreate(icicle); 
     Log.d(LOGid, "Create activity"); 
     setContentView(R.layout.download); 

     mContext = this; 


     tvCurrent = (TextView) findViewById(R.id.tvCurrentAction); 
     tvCurrent.setText("Awaiting user input"); 
     tvCurrent.invalidate(); 

     Button bDownload = (Button) findViewById(R.id.btnStartDownload); 
     bDownload.setOnClickListener(new View.OnClickListener() 
     { 
      public void onClick(View arg0) 
      { 
       if (!isNetworkAvailable()) 
       { 
        AlertDialog adConfirm = new AlertDialog.Builder(mContext).create(); 
        adConfirm.setCancelable(false); // This blocks the 'BACK' button 
        adConfirm.setMessage("It appears you are offline, phone should be online for this to work."); 
        adConfirm.setButton("I'm online, go ahead.", new DialogInterface.OnClickListener() 
        { 
         @Override 
         public void onClick(DialogInterface dialog, int which) 
         { 
          dialog.dismiss(); 
          downloadfiles(); 
         } 
        }); 
        adConfirm.setButton2("I'll try later", new DialogInterface.OnClickListener() 
        { 
         @Override 
         public void onClick(DialogInterface dialog, int which) 
         { 
          dialog.dismiss(); 
         } 
        }); 

        adConfirm.show(); 

       } 
       else 
       { 
        downloadfiles(); 
       } 
      } 
     }); 

     Button bDownloadInfo = (Button) findViewById(R.id.btnDownloadInfo); 
     bDownloadInfo.setOnClickListener(new View.OnClickListener() 
     { 
      public void onClick(View arg0) 
      { 
       AlertDialog adConfirm = new AlertDialog.Builder(mContext).create(); 
       adConfirm.setCancelable(false); // This blocks the 'BACK' button 
       adConfirm.setMessage("This function will go to the internet and download the Touch And Go 'Speak' free image set.\n\nIt is highly recommended that you use a wi-fi connection for this.\n\nThese images are provided free of charge and as is. They are not my work, but are based upon various free resources from the internet that I have pulled together.\nNo copyright infringement is intended. Please contact me if you wish to assert copyright for any of these images.\nIf you own a set of images from another source (for example the {PECS image set) the you can copy these to the applocation folder on the sdcard (" + msBaseFolder + ") - for every folder you want to display in the list you must have a corresponding image file for the app to display (for example if you have a folder called '2. Sentence Starters' then in the base folder you must have am image file called '2. Sentence Starters.jpg'"); 
       adConfirm.setButton("OK", new DialogInterface.OnClickListener() 
       { 
        @Override 
        public void onClick(DialogInterface dialog, int which) 
        { 
         dialog.dismiss(); 
        } 
       }); 

       adConfirm.show(); 
      } 
     }); 


    } 


    private void processManifest() 
    { 
     tvCurrent.setText("Processing files to download..."); 
     tvCurrent.invalidate(); 

     //Get the text file 
     File file = new File(msBaseFolder,LOCAL_FILE_MANIFEST); 
     Log.d(LOGid, "Created new file " + msBaseFolder+ "/" + LOCAL_FILE_MANIFEST); 

     //Read text from file 
//  StringBuilder text = new StringBuilder(); 
     ProgressBar pb = (ProgressBar) findViewById(R.id.barFiles); 
     int iLineCnt=getLineCount(LOCAL_FILE_MANIFEST); 

     int iCurrentLine=0; 
     pb.setMax(iLineCnt); 
     Log.d(LOGid, "Set progress line count to " + iCurrentLine + " of " + iLineCnt); 

     try 
     { 
      BufferedReader br = new BufferedReader(new FileReader(file)); 
      Log.d(LOGid, "Created buffered reader"); 
      String line; 

      while ((line = br.readLine()) != null) 
      { 
       try 
       { 
        iCurrentLine++; 
        pb.setProgress(iCurrentLine); 
        pb.invalidate(); 
        Log.d(LOGid, "Set progress line count to " + iCurrentLine + " of " + iLineCnt); 
       } 
       catch (Exception ex) 
       { // swallow the error 
       } 
       String[] sDownloads = line.split(";"); 
       Log.d(LOGid, "Line read was" + line + " of which there are " + sDownloads.length + " parts"); 

       // line should have 3 parts 
       // 1. Source url 
       // 2. Target name 
       // 3. Target folder 
       if (sDownloads.length == 3) 
       { 
        // Does the file already exist 
        File fil; 
        File fld; 
        if (sDownloads[2].equals(".")) 
        { 
         fil = new File(msBaseFolder, sDownloads[1]); 
         fld = new File(msBaseFolder); 
        } 
        else 
        { 
         fil = new File(msBaseFolder + "/" + sDownloads[2], sDownloads[1]); 
         fld = new File(msBaseFolder + "/" + sDownloads[2]); 
        } 

        // Does the folder exist 
        Log.d(LOGid, "Ensure the dest folder exists: " + fld.getPath()); 
        fld.mkdirs(); 

        if (!fil.exists()) 
        { 
         downloadFile(sDownloads[0], sDownloads[1], fld.getPath(), true); 
        } 
        else 
        { 
         // Skipping a file 
        } 
       } 
      } 
     } 
     catch (Exception e) 
     { 
      //You'll need to add proper error handling here 
      Log.e(LOGid, "Error in processmanifest:" + e.getMessage()); 
     } 

     //Set the text 
     tvCurrent.setText("Finished Downloading Files..."); 
     tvCurrent.invalidate(); 
    } 

    private boolean downloadFile(String _source, String _dest, String _Folder, boolean isManifest) 
    { 
     try 
     { 
      tvCurrent.setText("Downloading file " + _dest + "..."); 
      tvCurrent.invalidate(); 
      //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(_source); 
      Log.d(LOGid, "Created URL"); 

      //create the new connection 
      HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 
      Log.d(LOGid, "Created HTTP Connection"); 

      //set up some things on the connection 
      urlConnection.setRequestMethod("GET"); 
      Log.d(LOGid, "Set the request method"); 
      urlConnection.setDoOutput(true); 
      Log.d(LOGid, "Set doOutput"); 

      //and connect! 
      urlConnection.connect(); 
      Log.d(LOGid, "Connected the url connection"); 

      //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(_Folder, _dest); 
      Log.d(LOGid, "Created dest file, path=" + file.getPath() + "...file=" + file.getName()); 

      //this will be used to write the downloaded data into the file we created 
      FileOutputStream fileOutput = new FileOutputStream(file); 
      Log.d(LOGid, "Created file output stream"); 

      //this will be used in reading the data from the internet 
      InputStream inputStream = urlConnection.getInputStream(); 
      Log.d(LOGid, "Created Input stream"); 

      //this is the total size of the file 
      int totalSize = urlConnection.getContentLength(); 
      Log.d(LOGid, "Got total size " + totalSize); 

      //variable to store total downloaded bytes 
      int downloadedSize = 0; 

      //create a buffer... 
      byte[] buffer = new byte[1024]; 
      Log.d(LOGid, "Created buffer"); 

      int bufferLength = 0; //used to store a temporary size of the buffer 
      ProgressBar pb; 
      if (isManifest) 
      { 
       pb = (ProgressBar) findViewById(R.id.barManifest);  
      } 
      else 
      { 
       pb = (ProgressBar) findViewById(R.id.barOneFile);  
      } 
      pb.setMax(totalSize); 
      Log.d(LOGid, "Set progressbar size"); 

      pb.setProgress(0); 
      pb.invalidate(); 

      Log.d(LOGid, "Set progress to zero"); 

      //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); 
        Log.d(LOGid, "Wrote infor to the buffer"); 
        //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); 

        pb.setProgress(downloadedSize); 
        pb.invalidate(); 

        Log.d(LOGid, "Set progress to " + downloadedSize); 
      } 
      pb.setProgress(totalSize); 
      pb.invalidate(); 
      //close the output stream when done 
      fileOutput.close(); 
      Log.d(LOGid, "closed the output file"); 

      tvCurrent.setText("Finished Downloading file " + _dest + "..."); 
      tvCurrent.invalidate(); 

      //catch some possible errors... 
     } 
     catch (MalformedURLException e) 
     { 
      Log.d(LOGid, "Error dowloading file:" + e.getMessage() + "...malformed URL"); 
      return false; 
     } 
     catch (IOException e) 
     { 
      Log.d(LOGid, "Error dowloading file:" + e.getMessage()+ "...IO Exception"); 
      return false; 
     } 
     catch (Exception e) 
     { 
      Log.d(LOGid, "Error dowloading file:" + e.getMessage()+ "...generic exception"); 
      return false; 
     } 
     return true; 
    } 

    private boolean getBaseFolder() 
    { 
     try 
     { 
      msBaseFolder = Environment.getExternalStorageDirectory() + "/" + SpeakProperties.msAppFolder(getSharedPreferences(SpeakProperties.APP_NAME, 0)); 
      File f = new File(msBaseFolder); 
      if (!f.exists()) 
      { 
       msBaseFolder = Environment.getExternalStorageDirectory() + "/" + SpeakProperties.APP_DEF_FOLDER; 
       f = new File(msBaseFolder); 
      } 

      if (!f.exists()) 
      { 
       return createNewBaseFolder(); 
      } 
      else 
      { 
       Log.d(LOGid, "The base folder for this app" + msBaseFolder + " does exists."); 
       return true;     
      } 
     } 
     catch (Exception ex) 
     { 
      Log.d(LOGid, "Could not get base folder:" + msBaseFolder + ". Error:" + ex.getMessage()); 
      return false; 
     } 
    } 

    private boolean createNewBaseFolder() 
    { 

     tvCurrent.setText("Creating new base folder..."); 
     tvCurrent.invalidate(); 
     final String sNewBaseFld = Environment.getExternalStorageDirectory() + "/" + SpeakProperties.APP_DEF_FOLDER; 
     AlertDialog adDelete = new AlertDialog.Builder(this).create(); 
     adDelete.setCancelable(false); // This blocks the 'BACK' button 
     adDelete.setMessage("The base folder for the application does not seem to exist. \n\nWould you like to create one now based on the application default folder setting? \n\nThe App Default Folder is:" + sNewBaseFld); 
     adDelete.setButton("OK", new DialogInterface.OnClickListener() 
     { 
      @Override 
      public void onClick(DialogInterface dialog, int which) 
      { 
       try 
       { 
        File fCreate = new File(sNewBaseFld); 
        if (!fCreate.exists()) 
        { 
         fCreate.mkdirs(); 
        } 
       }     
       catch (Exception ex) 
       { 
        Log.e(LOGid, "Could not delete file:" + ex.getMessage()); 
        showToast("Could not create folder:" +sNewBaseFld + ". Error was:" + ex.getMessage()); 
       } 
       dialog.dismiss(); 
      } 
     }); 
     adDelete.setButton2("Cancel", new DialogInterface.OnClickListener() 
     { 
      @Override 
      public void onClick(DialogInterface dialog, int which) 
      { 
       dialog.dismiss(); 
      } 
     }); 

     adDelete.show(); 

     // Now did we create the folder? 
     File f = new File(sNewBaseFld); 
     tvCurrent.setText("Finished Creating new base folder..."); 
     tvCurrent.invalidate(); 
     return f.exists(); 
    } 

    void showToast(String msg) { 
     AlertDialog ad = new AlertDialog.Builder(this).create(); 
     ad.setCancelable(false); // This blocks the 'BACK' button 
     ad.setMessage(msg); 
     ad.setButton("OK", new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       dialog.dismiss(); 
      } 
     }); 
     ad.show(); 

    } 

    private void downloadfiles() 
    { 
     CheckBox cb = (CheckBox) findViewById(R.id.cbDownload); 
     if (!cb.isChecked()) 
     { 
      return; 
     } 

     if (!getBaseFolder()) 
     { 
      return; 
     } 

     if (downloadFile(FILE_MANIFEST, LOCAL_FILE_MANIFEST, msBaseFolder, true)) 
     { 
      processManifest(); 
     } 
     else 
     { 
      AlertDialog adConfirm = new AlertDialog.Builder(mContext).create(); 
      adConfirm.setCancelable(false); // This blocks the 'BACK' button 
      adConfirm.setMessage("Could not download the list of image files, perhaps you are offline?"); 
      adConfirm.setButton("OK.", new DialogInterface.OnClickListener() 
      { 
       @Override 
       public void onClick(DialogInterface dialog, int which) 
       { 
        dialog.dismiss(); 
       } 
      }); 

      adConfirm.show(); 

     } 
    } 

    private boolean isThereANewDownload() 
    { 
     tvCurrent.setText("Checking to see if there are new images..."); 
     tvCurrent.invalidate(); 
     // check if we have a TouchAndGoSpeak.manifest file on the sd card 
     File file = new File(msBaseFolder,LOCAL_FILE_MANIFEST); 
     if (!file.exists()) 
     { 
      Log.d(LOGid, "No Local Manifest so returning true"); 
      return true; 
     } 

     // if we have one then the user has downloaded the manifest before 
     // download the new file 

     Log.d(LOGid, "We have a Local Manifest getting again to check"); 
     if (downloadFile(FILE_MANIFEST, LOCAL_FILE_MANIFEST + ".new", msBaseFolder, false)) 
     { 
      return (compare(LOCAL_FILE_MANIFEST, LOCAL_FILE_MANIFEST + ".new")); 
     } 
     else 
     { 
      AlertDialog adConfirm = new AlertDialog.Builder(mContext).create(); 
      adConfirm.setCancelable(false); // This blocks the 'BACK' button 
      adConfirm.setMessage("Could not download the list of image files, perhaps you are offline? Unable to check if there are new files. Will try and download all files next."); 
      adConfirm.setButton("OK.", new DialogInterface.OnClickListener() 
      { 
       @Override 
       public void onClick(DialogInterface dialog, int which) 
       { 
        dialog.dismiss(); 
       } 
      }); 

      adConfirm.show(); 
      return true; 
     } 
    } 

    private int getLineCount(String _File) 
    { 
     int iLineCount = 0; 
     //Get the text file 
     File file = new File(msBaseFolder,_File); 
//  StringList sl_source = new StringList(); 

     try 
     { 
      BufferedReader br = new BufferedReader(new FileReader(file)); 
      String line; 

      while ((line = br.readLine()) != null) 
      { 
       iLineCount++; 
      } 
     } 
     catch (IOException e) 
     { 
      //You'll need to add proper error handling here 
     } 
     return iLineCount; 
    } 


    private boolean compare(String _File1, String _File2) 
    { 
     Log.d(LOGid, "Comparing the 2 files"); 

     //Get the text file 
     File file = new File(msBaseFolder,_File1); 
//  StringList sl_source = new StringList(); 
     ArrayList<String> _original_data = new ArrayList<String>(); 
     ArrayList<String> _new_data = new ArrayList<String>(); 

     try { 
      BufferedReader br = new BufferedReader(new FileReader(file)); 
      String line; 

      while ((line = br.readLine()) != null) 
      { 
       _original_data.add(line); 
      } 
     } 
     catch (IOException e) 
     { 
      //You'll need to add proper error handling here 
     } 

     file = new File(msBaseFolder,_File2); 
     try 
     { 
      BufferedReader br = new BufferedReader(new FileReader(file)); 
      String line; 

      while ((line = br.readLine()) != null) 
      { 
       _new_data.add(line); 
      } 
     } 
     catch (IOException e) 
     { 
      //You'll need to add proper error handling here 
     } 

     return _original_data.equals(_new_data);  
    } 

    /** 
    * @return the networkAvailable 
    */ 
    public boolean isNetworkAvailable() 
    { 

     boolean networkAvailable = true; 
     try 
     { 
      Context c = getApplicationContext(); 
      ConnectivityManager connectionManager = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE); 
      networkAvailable = connectionManager.getActiveNetworkInfo() != null && connectionManager.getActiveNetworkInfo().isConnected(); 
     } 
     catch (Exception ex) 
     { 
      Log.d(LOGid, "Error determining the network connectivity:" + ex.getClass().toString() + " message:" + ex.getMessage()); 
     } 
     return networkAvailable; 
    }  

    private Context mContext; 
} 

編集:作業downloadFiles方法プログレスバーと

私の最後のdownloadFileは、スレッドとハンドラを追加して、次のようになります更新。 mHandlerは、UIのonCreate内でインスタンス化されるプライベートクラス変数です。

ありがとうございました!

private boolean downloadFile(String _source, String _dest, String _Folder, 
     boolean isManifest) 
{ 
    m_downloadSuccess = true; 
    m_source = _source; 
    m_dest = _dest; 
    m_Folder = _Folder; 
    if (isManifest) 
    { 
     m_pb = (ProgressBar) findViewById(R.id.barManifest); 
    } 
    else 
    { 
     m_pb = (ProgressBar) findViewById(R.id.barOneFile); 
    } 

    // Start lengthy operation in a background thread 
    new Thread(new Runnable() 
    { 
     public void run() 
     { 
      try 
      { 
       // Update the progress bar 
       mHandler.post(new Runnable() 
       { 
        public void run() 
        { 
         Log.d(LOGid, "Set File max progress to " + mFileTotal); 
         Log.d(LOGid, "Set File progress to 0"); 
         Log.d(LOGid, "Downloading file " + m_dest + "..."); 
         tvCurrent.setText("Downloading file " + m_dest + "..."); 
        } 
       }); 

       // 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(m_source); 
       Log.d(LOGid, "Created URL"); 

       // create the new connection 
       HttpURLConnection urlConnection = (HttpURLConnection) url 
         .openConnection(); 
       Log.d(LOGid, "Created HTTP Connection"); 

       // set up some things on the connection 
       urlConnection.setRequestMethod("GET"); 
       Log.d(LOGid, "Set the request method"); 
       urlConnection.setDoOutput(true); 
       Log.d(LOGid, "Set doOutput"); 

       // and connect! 
       urlConnection.connect(); 
       Log.d(LOGid, "Connected the url connection"); 

       // 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(m_Folder, m_dest); 
       Log.d(LOGid, "Created dest file, path=" + file.getPath() 
         + "...file=" + file.getName()); 

       // this will be used to write the downloaded data into the 
       // file we created 
       FileOutputStream fileOutput = new FileOutputStream(file); 
       Log.d(LOGid, "Created file output stream"); 

       // this will be used in reading the data from the internet 
       InputStream inputStream = urlConnection.getInputStream(); 
       Log.d(LOGid, "Created Input stream"); 

       // this is the total size of the file 
       mTotalSize = urlConnection.getContentLength(); 
       Log.d(LOGid, "Got total size " + mTotalSize); 

       // variable to store total downloaded bytes 
       int downloadedSize = 0; 

       // create a buffer... 
       byte[] buffer = new byte[1024]; 
       Log.d(LOGid, "Created buffer"); 

       int bufferLength = 0; // used to store a temporary size of 
             // the buffer 

       mProgressCurrentFileStatus = 0; 
       // m_pb.setProgress(0); 
       Log.d(LOGid, "Set progress to zero"); 

       // Update the progress bar 
       mHandler.post(new Runnable() 
       { 
        public void run() 
        { 
         Log.d(LOGid, "Set progress totalsize to " + mTotalSize); 
         m_pb.setMax(mTotalSize); 

         Log.d(LOGid, "Set File progress to " + mFileCount); 


         Log.d(LOGid, "Set progress to:" + mProgressCurrentFileStatus); 
         m_pb.setProgress(mProgressCurrentFileStatus); 
        } 
       }); 

       // 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); 
        Log.d(LOGid, "Wrote infor to the buffer"); 
        // 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); 

        mProgressCurrentFileStatus = downloadedSize; 
        // Update the progress bar 
        mHandler.post(new Runnable() 
        { 
         public void run() 
         { 
          Log.d(LOGid, "Set progress size:" + mTotalSize); 
          m_pb.setMax(mTotalSize); 

          Log.d(LOGid, "Set progress to:" + mProgressCurrentFileStatus); 
          m_pb.setProgress(mProgressCurrentFileStatus); 
         } 
        }); 

        Log.d(LOGid, "Set progress to " + downloadedSize); 
       } 
       // close the output stream when done 
       fileOutput.close(); 
       Log.d(LOGid, "closed the output file"); 

       mHandler.post(new Runnable() 
       { 
        public void run() 
        { 
         tvCurrent.setText("Finished Downloading file " + m_dest + "..."); 
        } 
       }); 
       m_downloadSuccess = true; 
       // catch some possible errors... 
      } catch (MalformedURLException e) 
      { 
       Log.d(LOGid, "Error dowloading file:" + e.getMessage() 
         + "...malformed URL"); 
       m_downloadSuccess = false; 
      } catch (IOException e) 
      { 
       Log.d(LOGid, "Error dowloading file:" + e.getMessage() 
         + "...IO Exception"); 
       m_downloadSuccess = false; 
      } catch (Exception e) 
      { 
       Log.d(LOGid, "Error dowloading file:" + e.getMessage() 
         + "...generic exception"); 
       m_downloadSuccess = false; 
      } 
     } 
    }).start(); 

    return m_downloadSuccess; 
} 
+0

すべてのログ設定が表示されますか? – Snicolas

+0

はい、ダウンロードは動作し、ログには更新が表示されます。 –

答えて

4

あなたが内のあなたのUIスレッド(新しいスレッド内に位置していない、コールバックから直接呼び出す)の進捗状況を測定している仕事をやっているように見えます。これは、システムにあなたの暫定進捗状況の更新に対応するためのCPU時間を与えません。

これを処理する適切な方法は、バックグラウンドスレッドで作業を行い、進行状況を定期的に更新することです。これらの更新はUIスレッド内から行われなければなりませんが、アクティビティのrunOnUiThread(Runnable)メソッドはそれを実現します。 (別の方法としては、UIスレッド実行のためのあなたの活動のハンドラに実行可能を投稿することができます。)

編集:は、あなたの仕事はあなたのdownloadFiles()メソッドで行われ スレッドの作成のための例を追加しましたので、これはあなたが何をしたいです別のスレッド。 downloadFiles(あなたの呼び出しを置き換え)で、例えば、

Thread worker = new Thread(new Runnable() { 
    @Override 
    public void run() { 
     downloadFiles(); 
    } 
}); 
worker.start(); 

今すぐあなたもdownloadFilesを変更する必要があります() - それはUIスレッドではありませんので、UIを変更することは許されないです。 pb.setMax(totalSize);を呼び出す代わりに、UIスレッド内で実行する必要があります。あなたのRunnableの -

runOnUiThread(new Runnable() { 
    @Override 
    public void run() { 
     // do things that modify the UI 
    } 
}); 

あなたはここに注意する必要がある唯一の事:あなたは、新しいスレッドを実行する実行可能(またはそれらのいくつかは)同様の方法で、適切なスレッドからUIを変更するために書くことができますrun()メソッドは、おそらくrunOnUiThread()呼び出しを含むメソッド内のいくつかのローカル変数にアクセスする必要があります。合法的にそのアクセスを提供するには、を使用する変数はとなる必要があります。finalです。最終変数にできない変数がある場合は、その値を実行可能ファイルが使用する最終変数にコピーする必要があります。例:

final ProgressBar final_pb = pb; 
final int final_downloadedSize = downloadedSize; 
runOnUiThread(new Runnable() { 
    @Override 
    public void run() { 
     final_pb.setProgress(final_downloadedSize); 
    } 
}); 
+0

OK、それは私が考えていたものではありません。これは良いアプローチのようです。私はJava/Androidのスレッドに精通していません。機会があれば、自分のUIを更新できるスレッドをスピンオフする方法の基本的な例を尋ねることができます。 –

+0

この回答は正しいです。これを行う方法の例が必要な場合は、Androidサンプルコード(ApiDemos/src/com/example/android/apis/app/AlertDialogSamples.java)のApiDemosアプリケーションに1つあります。私が卵を吸う方法を教えようとしているなら、私の謝罪。 –

関連する問題