2015-04-22 60 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