2012-06-17 89 views
1

我已經做了一個代碼,將從互聯網上下載文件。但問題是我的手機會凍結(無響應),直到下載完成。我使用的手機是Xperia Arc S和Galaxy S2。無論如何解決這個問題?安卓手機凍結在asynctask下載

@Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.staffchoices);  

     MyI = new Intent(getApplicationContext(), MaxAppsAct.class); 
     MyPI = PendingIntent.getActivity(getApplicationContext(), 0, MyI, 0); 
     MyNM = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); 

     Intent intent = new Intent(getApplicationContext(), MaxAppsAct.class); 
     final PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0); 

     notification = new Notification(R.drawable.logo, "Downloading...", System.currentTimeMillis()); 
     notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT; 
     notification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.staffchoices); 
     notification.contentIntent = pendingIntent; 
     notification.contentView.setImageViewResource(R.id.imgIcon, R.drawable.save); 
     notification.contentView.setTextViewText(R.id.tvText, "Downloading..."); 
     notification.contentView.setProgressBar(R.id.pbStatus, 100, progress, false); 
     notificationManager = (NotificationManager) getApplicationContext().getSystemService(getApplicationContext().NOTIFICATION_SERVICE); 
     notificationManager.notify(42, notification); 

     String url = "http://www.domainURL.com/3d.png"; 
     new DownloadFileAsync().execute(url); 
     } 

     public class DownloadFileAsync extends AsyncTask<String, Integer, Void> { 

     @Override 
     protected void onPreExecute(){ 
      super.onPreExecute(); 
      } 

     @Override 
     protected Void doInBackground(String... aurl) { 
      int count; 
      try { 
       URL url = new URL(aurl[0]); 
       URLConnection conexion = url.openConnection(); 
       conexion.connect(); 

       int lengthOfFile = conexion.getContentLength(); 
       Log.d("ANDRO_ASYNC", "Lenght of file: " + lengthOfFile); 

       File folder = new File(Environment.getExternalStorageDirectory() + "/MaxApps"); 
       boolean success = false; 
       if (!folder.exists()) { 
        success = folder.mkdirs(); 
       } 
       if (!success) { 
       } else { 
       } 

       InputStream input = new BufferedInputStream(url.openStream()); 
       OutputStream output = new FileOutputStream("/sdcard/MaxApps/3d.png"); 

       byte data[] = new byte[1024]; 

       long total = 0; 

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

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

      return null; 
     } 

     @Override 
     protected void onProgressUpdate(Integer... progress) {   
      notification.contentView.setProgressBar(R.id.pbStatus, 100, progress[0], false); 
      notificationManager.notify(42, notification); 
      } 

     protected void onPostExecute(String unused) { 
      notificationManager.cancel(42); 

      Notification MyN = new Notification(); MyN.icon = R.drawable.logo1; 
      MyN.tickerText = "Download Complete"; 
      MyN.number = 1; 
      MyN.setLatestEventInfo (getApplicationContext(), "Application Title", "Application Description", MyPI); 

      MyNM.notify(1, MyN); 
     } 
    } 
} 
+0

當你說的「手機會凍結「是否包括如果你點擊主頁按鈕什麼都不會發生?你在手機上運行的是什麼版本的Android? – MikeIsrael

+0

將緩衝區(字節數組)的大小增加到一個更大的值,例如16 * 1024(16K)時會發生什麼? – Rajesh

+0

@Rajesh,thx對於建議,現在的表現要好得多,但並沒有預期的那麼順利。我打算做這樣的事情,但沒有迴應。如果(total%(lengthOfFile/20)== 0){0} { \t \t \t \t \t publishProgress((int)((total * 100)/ lengthOfFile)); \t \t \t \t} – melvintcs

回答

3

性能瓶頸似乎是調用publishProgress的頻率。您應該設計一種方式,讓您不經常發佈進度,而不會影響用戶體驗。

建議:

  1. 增加緩衝區大小,以一個合理的值,像16K或32K
  2. 更改發佈機制的進展情況如下:

    while ((count = input.read(data)) != -1) { 
        total += count; 
        int progressPercent = (int) ((total*100)/lengthOfFile); 
        if(progressPercent % 20 == 0){ //publish progress on completion of every 20% 
         publishProgress(progressPercent); 
        } 
        output.write(data, 0, count); 
    }