2011-10-12 152 views
0

我開發了一個應用程序,它從互聯網獲取內容並在設備的屏幕上顯示相應內容。該程序運行良好,有點慢。大約需要3-4秒來加載和顯示內容。我想將我的代碼放在後臺線程中完成所有工作(獲取Web內容並顯示它)。另外,我想展示一個進度對話框。Android異步任務下載失敗err

public class Activity1 extends Activity 
{ 
    private ProgressDialog progressDialog; 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     new AsyncTask<Integer, Integer, Boolean>() 
     { 
      ProgressDialog progressDialog; 

      @Override 
      protected void onPreExecute() 
      { 
       /* 
       * This is executed on UI thread before doInBackground(). It is 
       * the perfect place to show the progress dialog. 
       */ 
       progressDialog = ProgressDialog.show(Activity1.this, "", 
         "Loading..."); 
      } 

      @Override 
      protected Boolean doInBackground(Integer... params) 
      { 
       if (params == null) 
       { 
        return false; 
       } 
       try 
       { 
        /* 
        * This is run on a background thread, so we can sleep here 
        * or do whatever we want without blocking UI thread. A more 
        * advanced use would download chunks of fixed size and call 
        * publishProgress(); 
        */ 
        Thread.sleep(params[0]); 
        // HERE I'VE PUT ALL THE FUNCTIONS THAT WORK FOR ME 
       } 
       catch (Exception e) 
       { 
        Log.e("tag", e.getMessage()); 
        /* 
        * The task failed 
        */ 
        return false; 
       } 

       /* 
       * The task succeeded 
       */ 
       return true; 
      } 

      @Override 
      protected void onPostExecute(Boolean result) 
      { 
       progressDialog.dismiss(); 
       /* 
       * Update here your view objects with content from download. It 
       * is save to dismiss dialogs, update views, etc., since we are 
       * working on UI thread. 
       */ 
       AlertDialog.Builder b = new AlertDialog.Builder(Activity1.this); 
       b.setTitle(android.R.string.dialog_alert_title); 
       if (result) 
       { 
        b.setMessage("Download succeeded"); 
       } 
       else 
       { 
        b.setMessage("Download failed"); 
       } 
       b.setPositiveButton(getString(android.R.string.ok), 
         new DialogInterface.OnClickListener() 
         { 

          @Override 
          public void onClick(DialogInterface dlg, int arg1) 
          { 
           dlg.dismiss(); 
          } 
         }); 
       b.create().show(); 
      } 
     }.execute(2000); 

     /* new Thread() 
     { 
      @Override 
      public void run() 
      { 

       // dismiss the progressdialog 
       progressDialog.dismiss(); 
      } 
     }.start(); 
    }*/ 
} 

如果我用這段代碼運行應用程序,我得到這個:download failed。另一方面,如果我保留最終線程,則應用程序崩潰,NullPointerException。我真的不知道該做什麼了。

我真的很滿意,如果你可以給我一個替代這個代碼,不只是一些提示,因爲我是新來的android和我真的不知道很多。謝謝。

UPDATE:

我不想顯示下載進度,我想顯示的進度對話框,直到應用程序已準備好顯示的全部內容。

+0

訪問此http://stackoverflow.com/questions/3028306/download-a-file-with-android-and-showing-the-progress-in-a-progressdialog – kehnar

+0

有沒有必要Thread.sleep(params [0]);因爲AsyncTask是無痛線程本身,所以你不需要關心線程。 –

+0

你的日誌說什麼? – Maggie

回答

2

最好的方法是使用AsyncTask類,因爲它可以讓你執行一些後臺進程並同時更新UI(在你的情況下,它是一個進度條)。

這是一個例子代碼:

ProgressDialog mProgressDialog = new ProgressDialog(YourActivity.this); 
mProgressDialog.setMessage("A message"); 
mProgressDialog.setIndeterminate(false); 
mProgressDialog.setMax(100); 
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
DownloadFile downloadFile = new DownloadFile(); 
downloadFile.execute("the url to the file you want to download"); 

的的AsyncTask將看起來像這樣:

private class DownloadFile extends AsyncTask<String, Integer, String>{ 
    @Override 
    protected String doInBackground(String... url) { 
     int count; 
     try { 
      URL url = new URL(url[0]); 
      URLConnection conexion = url.openConnection(); 
      conexion.connect(); 
      // this will be useful so that you can show a tipical 0-100% progress bar 
      int lenghtOfFile = conexion.getContentLength(); 

      // downlod the file 
      InputStream input = new BufferedInputStream(url.openStream()); 
      OutputStream output = new FileOutputStream("/sdcard/somewhere/nameofthefile.ext"); 

      byte data[] = new byte[1024]; 

      long total = 0; 

      while ((count = input.read(data)) != -1) { 
       total += count; 
       // publishing the progress.... 
       publishProgress((int)(total*100/lenghtOfFile)); 
       output.write(data, 0, count); 
      } 

      output.flush(); 
      output.close(); 
      input.close(); 
     } catch (Exception e) {} 
     return null; 
    } 

上述(doInBackground)的方法,始終運行在後臺線程。你不應該在那裏做任何UI任務。在另一方面,onProgressUpdate運行在UI線程上,所以你會改變進度條:如果要執行一次文件的一些代碼

@Override 
public void onProgressUpdate(String... args){ 
    // here you will have to update the progressbar 
    // with something like 
    mProgressDialog.setProgress(args[0]); 
} 

} 你也想重寫onPostExecute方法已完全下載。

+0

是的..好複製/粘貼..我已經看到了該帖子在stackoverflow ..這不是我想要 – Teo

+0

訪問這裏http://www.tutorials-android.com/learn/How_to_display_a_progress_dialog_while_computing.rhtml和http:///www.helloandroid.com/tutorials/using-threads-and-progressdialog – kehnar

1

您應該創建的AsyncTask的內部類是這樣的:

private class YourTask extends AsyncTask<Context, Void, Void> 
{ 

ProgressDialog dialog = new ProgressDialog(mContext); 

    protected void onPreExecute() 
    { 
     dialog.setMessage("loading.."); 
     dialog.show(); 
    } 

    protected Void doInBackground(Context... params) 
    { 

        // ... 


     return null; 
    } 

    protected void onPostExecute(final Void unused) 
    { 
     dialog.dismiss(); 
    } 
} 

和的onCreate()提出:

 new YourTask().execute(); 

和更詳細的,你應該這樣一次檢查:

http://developer.android.com/reference/android/os/AsyncTask.html

0

當您使用新線程時,應用程序崩潰是因爲進度對話框未初始化有

裏面新的線程使用:

`progressDialog = ProgressDialog.show(Activity1.this, "","Loading..."); 

以及有關警告對話框:基本上要麼params爲null或邏輯是拋出一些異常。它沒有返回true 所以檢查ddms日誌並在這裏發佈。

`