2011-07-25 74 views
1

我試圖導出一個CSV文件到SD卡與AsyncTask和使用ProgressBar告訴用戶該任務如何運行。但是,當我嘗試設置進度條setProgress時,我收到一個空指針異常。我的Logcat顯示我傳遞的整數爲8,因此它不爲null。如果我註釋掉我嘗試設置進度條,它會正確運行。當我嘗試設置進度條時,運行時看到的是什麼?嘗試設置Asynctask中的水平進度條拋出NullPointerException

完整的AsyncTask實現:

public class Exporter extends AsyncTask<File, Integer, Boolean> { 
    private Context ctx; 
    private final static String TAG = "Exporter"; 

    private ProgressDialog progress; 

    private GeoDatabase db; 
    private RecordListActivity parent; 

    public Exporter(Context ctx) { 
     super(); 
     Log.d(TAG, "Building " + this + " from " + ctx); 
     this.ctx = ctx; 
     parent = (RecordListActivity) ctx; 
     db = (GeoDatabase) ctx.getApplicationContext(); 
    } 

    @Override 
    protected void onPreExecute() { 
     // Initialize the progress dialog 
     Log.i(TAG, "Pre-executing exporter"); 
     final String title = "Exporting"; 
     final String msg = "Initializing export..."; 
     progress = ProgressDialog.show(ctx, title, msg, true); 
     progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 

     super.onPreExecute(); 
    } 

    /** 
    * Begins operation of the exporter and determines if it was a 
    * success. 
    * 
    * @param args the destination file 
    * 
    * @return whether the transfer was successful 
    */ 
    @Override 
    protected Boolean doInBackground(final File... args) { 
     Log.d(TAG, "src-> " + "N/A" + ", dest-> " + args[0]); 

     // Get the ArrayList of records inside the current folder 
     ArrayList<Record> records = db.getRecordsIn(parent.getCurrentFolder()); 

     FileWriter writer; 
     try { 
      // Build a FileWriter targeting the destination 
      writer = new FileWriter(args[0]); 

      // Iterate through the records to write their CSV string out 
      final int total = records.size(); 
      int current = 1; 
      for (Record record : records) { 
       Log.v(TAG, "Accessing " + record); 
       writer.write(record.getCSVString() + "\n"); 
       Log.v(TAG, record.getCSVString()); 

       // Update the progress bar 
       onProgressUpdate(total, current); 
       current++; 
      } 

      // Close the writer 
      writer.close(); 
      Log.d(TAG, "Writer closed"); 
     } catch (IOException e) { 
      // Something has gone horribly wrong 
      e.printStackTrace(); 
      Log.e(TAG, "Writing to file failed!"); 
      return false; 
     } 

     return true; 
    } 

    @Override 
    protected void onProgressUpdate(Integer... values) { 
      // values[1] is the current record being written 
     // values[0] is the total number of records being written 
     final int total = values[0]; 
     final int current = values[1]; 

     // Updates the text for the current record 
     final String msg = "Writing record " + current + " of " + total; 
     progress.setMessage(msg); 
     Log.d(TAG, msg); 

     // Updates the progress bar 
     final int position = 100 * current/total; 
     Log.d(TAG, "Setting position to " + position); 
     progress.setProgress(position); 
    } 

    // can use UI thread here 
    protected void onPostExecute(final Boolean success) { 
     // TODO: Alert the user to success or failure - the dialog drops 
     // to quickly now 
     if (success) { 
      progress.setMessage("Export successful"); 
      Log.i(TAG, "Export successful"); 
     } else { 
      progress.setMessage("Export failed"); 
      Log.e(TAG, "Export failed"); 
     } 
     progress.dismiss(); 
    } 
} 

全相關的logcat:

24236  RecordListActivity D Export button pressed 
24236  RecordListActivity D Calling exporter to write out data 
24236  RecordListActivity D Building the dialog for exporting 
24236  RecordListActivity D OK clicked on export dialog 
24236    Exporter D Building [email protected] from [email protected] 
24236    Exporter I Pre-executing exporter 
24236    Exporter D src-> N/A, dest-> /mnt/sdcard/data.csv 
24236    Exporter V Accessing [email protected] 
24236    Exporter V 1, 1311358183278, latitude for bedding, longitude for bedding, strike, dip, observed a bedding , dip-direct 
24236    Exporter D Writing record 1 of 12 
24236    Exporter D Setting position to 8 
24236    dalvikvm W threadid=9: thread exiting with uncaught exception (group=0x401ab760) 
24236   AndroidRuntime E FATAL EXCEPTION: AsyncTask #1 
24236   AndroidRuntime E java.lang.RuntimeException: An error occured while executing doInBackground() 
24236   AndroidRuntime E at android.os.AsyncTask$3.done(AsyncTask.java:266) 
24236   AndroidRuntime E at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
24236   AndroidRuntime E at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
24236   AndroidRuntime E at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
24236   AndroidRuntime E at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
24236   AndroidRuntime E at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1081) 
24236   AndroidRuntime E at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:574) 
24236   AndroidRuntime E at java.lang.Thread.run(Thread.java:1020) 
24236   AndroidRuntime E Caused by: java.lang.NullPointerException 
24236   AndroidRuntime E at android.app.ProgressDialog.onProgressChanged(ProgressDialog.java:346) 
24236   AndroidRuntime E at android.app.ProgressDialog.setProgress(ProgressDialog.java:207) 
24236   AndroidRuntime E at edu.lafayette.cs.geology.Exporter.onProgressUpdate(Exporter.java:114) 
24236   AndroidRuntime E at edu.lafayette.cs.geology.Exporter.doInBackground(Exporter.java:86) 
24236   AndroidRuntime E at edu.lafayette.cs.geology.Exporter.doInBackground(Exporter.java:1) 
24236   AndroidRuntime E at android.os.AsyncTask$2.call(AsyncTask.java:252) 
24236   AndroidRuntime E at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
24236   AndroidRuntime E ... 4 more 
+0

您可以發佈完整的日誌以及完整的'AsyncTask',包括'doInBackround'()嗎? – LuxuryMode

+0

@LuxuryMode完成。沒有多少額外的,但希望它有幫助。 – thegrinner

回答

1

發現問題和解決方法here。它似乎是Android API中的known bug,其中用於創建ProgressDialogProgressDialog.show(params)的工廠方法未正確設置更新處理程序。所以修改後的工作代碼如下:

@Override 
protected void onPreExecute() { 
    // Initialize the progress dialog 
    Log.i(TAG, "Pre-executing exporter"); 
    final String title = "Exporting"; 
    final String msg = "Initializing export..."; 
    progress = new ProgressDialog(ctx); 
    progress.setTitle(title); 
    progress.setMessage(msg);  
    progress.setIndeterminate(false); 
    progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
    super.onPreExecute(); 
}