2015-04-22 34 views
-3

我試圖使用asynctask從SQLite中讀取大約1000行。我還使用progressdialog來顯示進度。一切工作正常,當我進入方法onPostExecute()我關閉對話框,並嘗試更新主線程上的整個行。對話框消失,但用戶界面需要很多更新。 在doInBackground()方法中,我填充一個tablelayout並將其返回給onPostExecute()。 如何顯示progressdialog,直到主線程完全填充?使用AsyncTask更新Android中的UI

private class FillTable extends AsyncTask<Void, Integer, TableLayout>{ 
     private File file; 
     private ProgressDialog pleaseWaitDialog; 
     private Context ctx; 
     private int colCount; 
     private int linCount; 
     private ScrollView scroolView; 
     private SQLiteDatabase db; 
     private Cursor cursor; 


     public FillTable(Context context, String newQuery){ 
      ctx = context; 
      scroolView = (ScrollView)ServiceActivity.this.findViewById(R.id.sv_service_vertical); 

      file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + getResources().getString(R.string.DATABASE_PATH), getResources().getString(R.string.DATABASE_NAME)); 
      if(!file.exists()) { 
       Toast.makeText(ctx, "Base de dados inválida ou não existe!", Toast.LENGTH_SHORT).show(); 
       this.cancel(true); 
      } 

      db = SQLiteDatabase.openOrCreateDatabase(file, null); 
      cursor = db.rawQuery(newQuery, null); 

      pleaseWaitDialog = new ProgressDialog(ctx); 
      pleaseWaitDialog.setCancelable(false); 
      pleaseWaitDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
     } 


     @Override 
     protected void onPreExecute(){ 

      scroolView.removeAllViews(); 

      colCount = cursor.getColumnCount(); 
      linCount = cursor.getCount(); 

      pleaseWaitDialog.setMax(linCount); 
      pleaseWaitDialog.setTitle("A ler a base de dados"); 
      pleaseWaitDialog.setMessage("Por favor aguarde..."); 
      pleaseWaitDialog.show(); 

      TextView tv = new TextView(ServiceActivity.this); 
      tv.setGravity(Gravity.CENTER_HORIZONTAL); 
      tv.setText("A apresentar resultados.\nPode demorar algum tempo!\n\nPor favor aguarde..."); 
      ((ScrollView)ServiceActivity.this.findViewById(R.id.sv_service_vertical)).addView(tv); 

      ((TextView)ServiceActivity.this.findViewById(R.id.tv_service_num_entradas)).setText(""); 
     } 


     @Override 
     protected TableLayout doInBackground(Void... params) { 

      TableLayout tableLayout = null; 

      if(cursor.moveToFirst()) { 

       tableLayout = new TableLayout(ServiceActivity.this); 

       //Preenchimento dos nomes das colunas 
       TextView textView; 
       TableRow tableRow = new TableRow(ServiceActivity.this); 

       for (int i = 0; i < colCount; i++) { 

        textView = new TextView(ServiceActivity.this); 

        if (i == 0) 
         textView.setText(cursor.getColumnName(i)); 
        else 
         textView.setText("\t" + cursor.getColumnName(i)); 

        textView.setTextColor(Color.MAGENTA); 
        tableRow.addView(textView); 
       } 

       tableLayout.addView(tableRow); 

       //Preenchimento das restantes linhas e das colunas de cada linha 
       int k = 1;//a contar com o cabeçalho 
       do { 

        this.publishProgress(k); 
        tableRow = new TableRow(ServiceActivity.this); 

        for (int i = 0; i < colCount; i++) { 
         textView = new TextView(ServiceActivity.this); 
         textView.setTextSize(11); 
         textView.setTextColor(Color.WHITE); 
         String str = cursor.getString(i); 

         if(str == null) { 
          if (i == 0) 
           textView.setText("..."); 
          else 
           textView.setText("\t" + "..."); 
         } 
         else{ 
          if (i == 0) 
           textView.setText(str); 
          else 
           textView.setText("\t" + str); 
         } 

         textView.setTextColor(Color.WHITE); 
         tableRow.addView(textView); 
        } 

        tableLayout.addView(tableRow); 
        k++; 

       } while (cursor.moveToNext()); 
      } 

      db.close(); 
      cursor.close(); 

      return tableLayout; 
     } 


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


     @Override 
     protected void onPostExecute(final TableLayout tl){ 

      scroolView.post(new Runnable() { 
       @Override 
       public void run() { 
        scroolView.removeAllViews(); 
        scroolView.addView(tl); 
        ((TextView)ServiceActivity.this.findViewById(R.id.tv_service_num_entradas)).setText("Nº de entradas: " + String.valueOf(linCount)); 
       } 
      }); 

      if(pleaseWaitDialog.isShowing()) 
       pleaseWaitDialog.dismiss(); 
     } 


     @Override 
     protected void onCancelled(final TableLayout tl){ 
      if(pleaseWaitDialog.isShowing()) 
       pleaseWaitDialog.dismiss(); 
      ((TextView)ServiceActivity.this.findViewById(R.id.tv_service_num_entradas)).setText("Nº de entradas: 0"); 
      scroolView.removeAllViews(); 
     } 
    } 

回答

1

你已經使用AsyncTask更新UI線程 - >很好。 但我似乎用AsyncTask錯誤的方式。

如果你想顯示進度對話框UTIL主線程(UI線程)充滿

定義:[YourClassToDoTask]延伸的AsyncTask < [ValueInput],[ValueUpdate],[ValueOutput]>

[ ValueUpdate]:是要更新到UI的行的對象。

使用3種方法:doInBackground,onProgressUpdate,onPostExecute

  1. doInBackground:做長期任務在後臺通過方法publishProgress([ValueUpdate]),以獲得來自任何來源,更新主線程數據
  2. onProgressUpdate:更新值到了doInBackground稱爲publishProgress([ValueUpdate])

    後UI線程3210

    onProgressUpdate(整數...進展) - > [ValueUpdate]是陣列或單個對象

    如果數組:[ValueUpdate] =進展

    如果單個對象:[ValueUpdate] =進展[0]

  3. onPostExecute:Dismis progressdialog(在這裏,UI線程總填)

+0

我想我明白你的意思,但我試圖更新tablerows而不是整個tablelayout但progressdialog塊主線程幾次durin g更新。你看到我更新的代碼了嗎? – ctx

+0

我看過你的代碼。你應該在onProgressUpdate中更新tablerow,不應該在doinBackground中更新,你爲什麼不使用ListView而是使用TableLayout? ListView讓你的UI變得流暢 – Anubis21DEC

+0

好的。我會嘗試更新onProgressUpdate()中的tablerow,並且我可能會更改爲listview。一旦我完成了,我會告訴你一些事情。謝謝。 – ctx