2012-04-30 69 views
7

Tôi có một mã đơn giản được cho là thực hiện một tác vụ, khi nút được nhấp tải xuống tệp, lưu tệp vào thẻ SD và mở tệp đó. Mọi thứ hoạt động ngoại trừ trong quá trình tải xuống, đối với các tệp lớn hơn, kết nối sẽ giảm và thanh tiến trình bị treo - hầu như luôn ở mức 20%. Tôi đã tìm kiếm và tìm kiếm và không thể tìm ra việc cần làm để giữ cho kết nối còn sống và cho phép tải xuống hoàn tất. Bất kỳ ý tưởng nào về cách giữ kết nối luôn hoạt động để quá trình tải xuống hoàn tất thay vì dừng ở mức 20%?Android - Tải xuống tệp lớn - sử dụng async/progressdialog

import java.io.BufferedInputStream; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.URL; 
import java.net.URLConnection; 
import java.util.List; 
import android.app.Activity; 
import android.app.ProgressDialog; 
import android.content.Intent; 
import android.content.pm.PackageManager; 
import android.net.Uri; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.os.Environment; 
import android.util.Log; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 

public class DownloadTestActivity extends Activity { 

    public static final int DIALOG_DOWNLOAD_PROGRESS = 0; 
    private Button startBtn; 
    private ProgressDialog mProgressDialog; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.main); 
      mProgressDialog = new ProgressDialog(DownloadTestActivity.this); 
      mProgressDialog.setMessage("Downloading..."); 
      mProgressDialog.setIndeterminate(false); 
      mProgressDialog.setMax(100); 
      mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 

      startBtn = (Button) findViewById(R.id.startBtn); 
      startBtn.setOnClickListener(new OnClickListener() { 
        public void onClick(View v) { 
          startDownload(); 
        } 
      }); 
    } 

    private void startDownload() { 
      DownloadFile downloadFile = new DownloadFile(); 
      downloadFile 
          .execute("http://www.website.com/file.pdf"); 

    } 

    class DownloadFile extends AsyncTask<String, Integer, String> { 

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

      @Override 
      protected void onProgressUpdate(Integer... progress) { 
        super.onProgressUpdate(progress); 
        mProgressDialog.setProgress(progress[0]); 
      } 

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

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

          InputStream input = new BufferedInputStream(url.openStream()); 
          String path = Environment.getExternalStorageDirectory() 
              + "/Android/Data/" 
              + getApplicationContext().getPackageName() + "/files"; 
          File file = new File(path); 
          file.mkdirs(); 
          File outputFile = new File(file, "test1.doc"); 
          OutputStream output = new FileOutputStream(outputFile); 

          byte data[] = new byte[8192]; 
          long total = 0; 
          int count; 
          while ((count = input.read(data)) != -1) { 
            total += count; 
            publishProgress((int) (total * 100/fileLength)); 
            output.write(data, 0, count); 
          } 

          output.flush(); 
          output.close(); 
          input.close(); 
          showPdf(); 

        } catch (Exception e) { 
        } 
        return null; 
      } 

      private void showPdf() { 
        // TODO Auto-generated method stub 
      if(mProgressDialog != null){ 
        mProgressDialog.dismiss(); 
      } 

        File file = new File(Environment.getExternalStorageDirectory() 
            + "/Android/Data/" 
            + getApplicationContext().getPackageName() 
            + "/files/test1.doc"); 
        PackageManager packageManager = getPackageManager(); 
        Intent testIntent = new Intent(Intent.ACTION_VIEW); 
        testIntent.setType("application/msword"); 
        List list = packageManager.queryIntentActivities(testIntent, 
            PackageManager.MATCH_DEFAULT_ONLY); 
        Intent intent = new Intent(); 
        intent.setAction(Intent.ACTION_VIEW); 
        Uri uri = Uri.fromFile(file); 
        intent.setDataAndType(uri, "application/msword"); 
        startActivity(intent); 
      } 


    } 
} 

Chỉnh sửa thông tin logcat:

--------- beginning of /dev/log/system 
W/InputManagerService( 199): Window already focused, ignoring focus gain of:  [email protected] 
--------- beginning of /dev/log/main 
D/AndroidRuntime(20673): 
D/AndroidRuntime(20673): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<< 
D/AndroidRuntime(20673): CheckJNI is OFF 
D/AndroidRuntime(20673): Calling main entry com.android.commands.pm.Pm 
D/AndroidRuntime(20673): Shutting down VM 
D/dalvikvm(20673): GC_CONCURRENT freed 101K, 82% free 467K/2560K, paused 1ms+0ms 
D/dalvikvm(20673): Debugger has detached; object registry had 1 entries 
I/AndroidRuntime(20673): NOTE: attach of thread 'Binder Thread #3' failed 
D/AndroidRuntime(20687): 
D/AndroidRuntime(20687): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<< 
D/AndroidRuntime(20687): CheckJNI is OFF 
D/AndroidRuntime(20687): Calling main entry com.android.commands.am.Am 
I/ActivityManager( 199): START {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.myapp/.Activity} from pid 20687 
D/AndroidRuntime(20687): Shutting down VM 
D/dalvikvm(20687): GC_CONCURRENT freed 102K, 81% free 489K/2560K, paused 0ms+0ms 
D/jdwp (20687): Got wake-up signal, bailing out of select 
D/dalvikvm(20687): Debugger has detached; object registry had 1 entries 
I/AndroidRuntime(20687): NOTE: attach of thread 'Binder Thread #3' failed 
D/dalvikvm(20698): Late-enabling CheckJNI 
I/ActivityManager( 199): Start proc com.myapp for activity  com.myapp/.Activity: pid=20698 uid=10102 gids={1015, 3003} 
I/dalvikvm(20698): Turning on JNI app bug workarounds for target SDK version 10... 
V/PhoneStatusBar( 271): setLightsOn(true) 
D/AudioHardware( 98): AudioHardware pcm playback is going to standby. 
D/AudioHardware( 98): closePcmOut_l() mPcmOpenCnt: 1 
I/ActivityManager( 199): Displayed com.myapp/.Activity: +197ms 
W/InputManagerService( 199): Starting input on non-focused client [email protected] (uid=10098 pid=20011) 
I/ActivityManager( 199): START {cmp=com.myapp/.Choice} from pid 20698 
D/AudioHardware( 98): AudioHardware pcm playback is exiting standby. 
D/AudioHardware( 98): openPcmOut_l() mPcmOpenCnt: 0 
V/PhoneStatusBar( 271): setLightsOn(true) 
I/ActivityManager( 199): Displayed com.myapp/.Choice: +93ms 
D/ANDRO_ASYNC(20698): Lenght of file: 736768 
D/dalvikvm(20698): GC_CONCURRENT freed 103K, 3% free 9403K/9607K, paused 2ms+3ms 
W/NetworkStats( 199): found non-monotonic values; saving to dropbox 
D/dalvikvm( 199): JIT code cache reset in 5 ms (1048440 bytes 13/0) 
D/dalvikvm( 199): GC_CONCURRENT freed 1472K, 13% free 24697K/28231K, paused 12ms+14ms 
D/AudioHardware( 98): AudioHardware pcm playback is going to standby. 
D/AudioHardware( 98): closePcmOut_l() mPcmOpenCnt: 1 
I/ActivityManager( 199): Force stopping package com.myapp uid=10102 
I/ActivityManager( 199): Killing proc 20698:com.myapp/10102: force stop 
W/ActivityManager( 199): Force removing ActivityRecord{41eb1ec0 com.myapp/.Choice}: app died, no saved state 
I/InputDispatcher( 199): Dropping event because there is no focused window or focused application. 
I/ActivityManager( 199): Force finishing activity ActivityRecord{418450c8 com.myapp/.Activity} 
I/InputDispatcher( 199): Dropping event because there is no focused window or focused application. 
W/InputDispatcher( 199): channel '417b41f0  com.myapp/com.myapp/.Activity (server)' ~  Consumer closed input channel or an error occurred. events=0x8 
E/InputDispatcher( 199): channel '417b41f0 com.myapp/com.myapp.Activity (server)' ~ Channel is unrecoverably broken and will be disposed! 
W/InputDispatcher( 199): Attempted to unregister already unregistered input channel '417b41f0 com.myapp/com.myapp.Activity (server)' 
W/WindowManager( 199): Failed looking up window 
W/WindowManager( 199): java.lang.IllegalArgumentException: Requested window [email protected] does not exist 
W/WindowManager( 199): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7176) 
W/WindowManager( 199): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7167) 
W/WindowManager( 199): at com.android.server.wm.WindowState$DeathRecipient.binderDied(WindowState.java:1545) 
W/WindowManager( 199): at android.os.BinderProxy.sendDeathNotice(Binder.java:417) 
W/WindowManager( 199): at dalvik.system.NativeStart.run(Native Method) 
I/WindowManager( 199): WIN DEATH: null 
I/WindowManager( 199): WIN DEATH: Window{4175b280  com.myapp/com.myapp.Choice paused=false} 
W/WindowManager( 199): Failed looking up window 
W/WindowManager( 199): java.lang.IllegalArgumentException: Requested window [email protected] does not exist 
W/WindowManager( 199): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7176) 
W/WindowManager( 199): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7167) 
W/WindowManager( 199): at com.android.server.wm.WindowState$DeathRecipient.binderDied(WindowState.java:1545) 
W/WindowManager( 199): at android.os.BinderProxy.sendDeathNotice(Binder.java:417) 
W/WindowManager( 199): at dalvik.system.NativeStart.run(Native Method) 
I/WindowManager( 199): WIN DEATH: null 
W/InputManagerService( 199): Got RemoteException sending setActive(false) notification to pid 20698 uid 10102 
D/dalvikvm(20011): GC_CONCURRENT freed 460K, 32% free 9468K/13767K, paused 3ms+4ms 
D/AudioHardware( 98): AudioHardware pcm playback is exiting standby. 
D/AudioHardware( 98): openPcmOut_l() mPcmOpenCnt: 0 
+0

Làm cách nào để xác định tệp 'lớn'? Cỡ nào? – Squonk

+0

Điện thoại có chuyển sang chế độ ngủ trong khi tải xuống không? – debracey

+0

@MisterSquonk - không quá lớn, khoảng 8MB. Tôi sẽ cần tải xuống tối đa khoảng 35MB. – user1363871

Trả lời

2

Tôi đã cố gắng tải xuống tệp của bạn một vài lần, trông giống như các cửa hàng tải xuống trong vài giây tại đây và ở đó và có thể kích hoạt hết thời gian chờ trong ứng dụng của bạn. Cố gắng chỉ định thời gian chờ rõ ràng trong khoảng 10-20 giây.

private DefaultHttpClient httpclient = new DefaultHttpClient(); 
private HttpGet get = new HttpGet("your url comes here"); 

protected String[] doInBackground(Void... v) { 
    HttpParams httpParameters = new BasicHttpParams(); 
    // set the timeout in milliseconds until a connection is established 
    // the default value is zero, that means the timeout is not used 
    int timeoutConnection = 3000; 
    HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); 
    // set the default socket timeout (SO_TIMEOUT) in milliseconds 
    // which is the timeout for waiting for data 
    int timeoutSocket = 5000; 
    HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket); 

    httpclient.setParams(httpParameters); 

    try { 
     HttpEntity entity = httpclient.execute(get).getEntity(); 
     FileOutputStream output = new FileOutputStream(outputFile); 
     entity.writeTo(output); 
     output.close(); 
     // return something, maybe? 
    } catch (ClientProtocolException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } finally { 
     httpclient.getConnectionManager().shutdown(); 
    } 
    return null; 
} 
+0

Tôi có nên thay đổi mã theo bất kỳ cách nào khác với thời gian chờ theo ý kiến ​​của bạn không? Tôi khá mới với điều này và tôi đang cố gắng học hỏi trên bay, nó sẽ là quá nhiều để yêu cầu một ví dụ về thời gian chờ? Cảm ơn! – user1363871

+0

Tôi đã thêm một ví dụ, nó sử dụng HttpClient thay vì url.connection, và bạn phải thêm đúng 'outputFile' biến cho tập tin đầu ra của bạn. – lenik

+0

Tôi hy vọng điều này sẽ giúp ai đó trải nghiệm cùng một vấn đề - chọn làm câu trả lời được chấp nhận. Cảm ơn. – user1363871

1

gì có vẻ là vấn đề là quá trình 199 trong logcat của bạn dường như là hoạt động của bạn, nhưng sau đó nó cho thấy:

I/ActivityManager( 199): Force stopping package com.viperean.atcassistant uid=10102 
I/ActivityManager( 199): Killing proc 20698:com.viperean.atcassistant/10102: force stop 
W/ActivityManager( 199): Force removing ActivityRecord{41eb1ec0 com.viperean.atcassistant/.atcChoice}: app died, no saved state 

(và dòng thứ hai cho thấy rằng nó đang giết chết asynctask của bạn ...).

Tôi không nghĩ rằng có bất kỳ điều gì sai với chính mã tải xuống. Tôi nghĩ bạn nên xem xét nhiều hơn trong hoạt động (bạn đang làm gì trong thời gian đó bên cạnh asynctask đó, bạn đang hiển thị những gì trên màn hình ... vv ...).

Dường như bạn ở mức thấp trong không gian vùng heap.

D/dalvikvm(20698): GC_CONCURRENT freed 103K, 3% free 9403K/9607K, paused 2ms+3ms 
D/dalvikvm( 199): JIT code cache reset in 5 ms (1048440 bytes 13/0) 
D/dalvikvm( 199): GC_CONCURRENT freed 1472K, 13% free 24697K/28231K, paused 12ms+14ms 

Đó là từ việc thu thập rác và xảy ra ngay trước khi ứng dụng của bạn bị lỗi, có thể đó cũng có thể là vấn đề?

+0

Tôi nghĩ rằng tôi có thể giải thích rằng, sau một chút thời gian chờ đợi trên tập tin tải về và nó sẽ không đi bất cứ nơi nào tôi đã "dài báo chí trở lại để chấm dứt" các ứng dụng. Vì vậy, đó là lý do tại sao nó bị giết và loại bỏ ... như của không gian đống tôi không biết phải nói gì. Tôi khởi động lại điện thoại và nó vẫn bị treo. – user1363871

+0

Tôi không biết nếu điều này có nghĩa là bất cứ điều gì, nhưng tôi đã thử nghiệm nhiều tệp trực tuyến để tải xuống. Lấy chiều dài của tập tin trong logcat và chia cho tỷ lệ phần trăm mà tải xuống dừng lại tôi luôn luôn nhận được một giá trị giữa 428799 - 471531 .. Điều này có nghĩa là bất cứ điều gì? Có lẽ với bộ đệm của tôi hoặc một cái gì đó như thế? – user1363871

1

mọi chuỗi trong Android sẽ bị hệ thống giết nếu hệ thống không phản hồi trong hơn năm phút. có thể bạn nên xem xét tải xuống dưới dạng dịch vụ hoặc ghi đè số onProgress và nhận chủ đề ở trạng thái còn sống

+0

Bạn có thể hiển thị hoặc liên kết tôi với một ví dụ để tải xuống dưới dạng dịch vụ không? – user1363871

+0

dường như tôi thích thực hiện onProgress sẽ là giải pháp tốt hơn – thepoosh

Các vấn đề liên quan