Показать Progressbar, пока я получаю записи из курсора - PullRequest
1 голос
/ 12 ноября 2010

У меня есть этот код:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.apod_eso2);  

    File f = new File(Environment.getExternalStorageDirectory() + 
        "/Database.sqlite"); 
    CursorFactory factory = null;   
    db =SQLiteDatabase.openDatabase(f.toString(),
        factory,SQLiteDatabase.NO_LOCALIZED_COLLATORS );

    ListView list=(ListView)findViewById(R.id.restaurantsApod);  
    KtiriaId=getIntent().getStringExtra(PrevIntent.ID_EXTRA);
    model=DbFileApodEso.getAllEntos(KtiriaId,db);


    startManagingCursor(model);
    //  
    adapter=new RestaurantAdapter(model);
    list.setAdapter(adapter);
    list.setOnItemClickListener(onListClick);  
}

и java-файл, который я получаю курсором:

public class DbFileApodEso {

    private static String TABLE_NAME="TempApodeiEn";
    private static String[] FROM = { "_id","name", "monthPaid",
        "fValue","gotPaid", };

    static Cursor getAllEntos(String id,SQLiteDatabase db) {

    String[] args={id,"0"};
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
    db.execSQL("CREATE TABLE " + TABLE_NAME + 
        "(_id INTEGER PRIMARY KEY  NOT NULL ,old_id integer " +
        " id1 INTEGER, id2 INTEGER, SNumber DOUBLE, name TEXT, gotPaid INTEGER, 
        monthPaid DATETIME, hmerej DATETIME, user TEXT,tMemo text, 
        GotThere INTEGER)");

    db.execSQL("INSERT INTO TempApodeiEn (old_id,eponimo, 
        monthPaid,iddiamerisma,fValue,gotPaid) " +
        "select _id,name,monthPaid,id2,fValue,
        gotPaid from ApodeiEn WHERE id2=? and gotPaid=?", args);

    return(db.query(TABLE_NAME, FROM, "id2=?  and gotPaid=?", args, null,
        null, null));
   }
}

Я заметил, что для выполнения требуется три секунды: model = DbFileApodEso.getAllEntos (KtiriaId, db) Итак, я бы хотел показать пользователю индикатор выполнения, чтобы понять, что что-то происходит. Как я могу это сделать?Спасибо за помощь

Я следовал инструкциям Shardul и код выглядит следующим образом:

    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.apod_eso2); 

    //DEFINING A NEW THREAD WHICH WOULD DO SOME WORK AND THEN DISMISS THE DIALOG 
    Thread workThread=new Thread(new Runnable(){

        @Override
        public void run() {
         //@ albertsmus :call your getAllEntos() here!
         File f = new File(Environment.getExternalStorageDirectory()+"/Eisprakseis.sqlite"); 
      CursorFactory factory = null; 

      db =SQLiteDatabase.openDatabase(f.toString(), factory,SQLiteDatabase.NO_LOCALIZED_COLLATORS );

      ListView list=(ListView)findViewById(R.id.restaurantsApod);
      KtiriaId=getIntent().getStringExtra(DiamEso.ID_EXTRA);
      EidosApod=getIntent().getStringExtra(DiamEso.ID_Eidos);
      String comment;   // The generated insult.
      model=DbFileApodEso.getAllEntos(KtiriaId,db);

      startManagingCursor(model);
      //  
      adapter=new RestaurantAdapter(model);
      list.setAdapter(adapter);
      list.setOnItemClickListener(onListClick);

            someTimeConsumingWork(5000);
            //ONLY ONE THREAD CAN HANDLE UI, INCLUDES DISSMISSAL OF
            //PROGRESS DIALOG. runOnUiThread WILL DO ITS MAGIC HERE!
            runOnUiThread(new Runnable(){

                @Override
                public void run() {
                    mProgressDialog.dismiss();
                    Toast.makeText(ApodEsoListaSec.this, "Work done!", Toast.LENGTH_LONG).show();
                }

            });
        }

    });
    workThread.start();

    mProgressDialog=ProgressDialog.show(this, "Work Notify!", "Working hard, Phew!");
}

 private void someTimeConsumingWork(long milisToWork){
     SystemClock.sleep(milisToWork);
 }

, но в итоге я получаю сообщение об ошибке ERROR / AndroidRuntime (6230): Причина: java.lang.RuntimeException: Не удается создать обработчик внутри потока, который не вызвал Looper.prepare (), почему это так?И когда я попытался отладить ошибку, я понял, что ошибка появляется, когда я вызываю: adapter = new RestaurantAdapter (model);Любое предложение?

Ответы [ 3 ]

0 голосов
/ 12 ноября 2010

Основная рабочая концепция - выполнять трудоемкую работу с фоновым (не-пользовательским) потоком.

В Android существует только один и только один поток пользовательского интерфейса.Вы должны обработать все изменения пользовательского интерфейса в этом отдельном потоке пользовательского интерфейса, т. Е. В вашем случае показ и отклонение ProgressDialog.

package .....;
.
.
import android.app.ProgressDialog;
.
.

public class WorkingClass extends Activity {
    ProgressDialog mProgressDialog;
.
.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    //DEFINING A NEW THREAD WHICH WOULD DO SOME WORK AND THEN DISMISS THE DIALOG 
    Thread workThread=new Thread(new Runnable(){

        @Override
        public void run() {
//@ albertsmus :call your getAllEntos() here!

            someTimeConsumingWork(5000);
            //ONLY ONE THREAD CAN HANDLE UI, INCLUDES DISSMISSAL OF
            //PROGRESS DIALOG. runOnUiThread WILL DO ITS MAGIC HERE!
            runOnUiThread(new Runnable(){

                @Override
                public void run() {
                    mProgressDialog.dismiss();
                    Toast.makeText(ContentProviderSample.this, "Work done!", Toast.LENGTH_LONG).show();
                }

            });
        }

    });
    workThread.start();

    mProgressDialog=ProgressDialog.show(this, "Work Notify!", "Working hard, Phew!");
}

private void someTimeConsumingWork(long milisToWork){
    SystemClock.sleep(milisToWork);
}

}

Я определил someTimeConsumingWork в этом примере Iзакодированы.Который в основном останавливает Thread на несколько долгих миллисекунд.Вы можете заменить этот вызов каким-нибудь реальным рабочим потоком, который потребляет время, в вашем случае albertsmus вызывает ваш getAllEntos () здесь.

Основное, что вы должны помнить, снова вы можететолько вызывайте и отклоняйте связанные с пользовательским интерфейсом функции только из потока пользовательского интерфейса , существуют другие классы и методы, которые могут помочь вам с той же целью, обработчик пользовательского интерфейса или AsynTask для более сложных функций.Вы можете найти их реализацию в документации.

Надеюсь, это поможет!

0 голосов
/ 17 ноября 2010

Ну, я использовал этот код, чтобы заставить его работать:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.apod_eso2); 
    File f = new File(Environment.getExternalStorageDirectory()+"/Eisprakseis.sqlite"); 

    getDatabaseRecs(f);

}
private void getDatabaseRecs(File fFile){   

            new ShowRecs().execute(fFile.toString());

}
public class ShowRecs extends AsyncTask<String, Void, Void> { 

    private String Content;  
    private String Error = null;   
    private ProgressDialog Dialog = new ProgressDialog(ApodEsoListaSec.this);  

     protected void onPreExecute() { 

         Dialog.setMessage("Please Wait!..");  
         Dialog.show();  
     }  

     protected Void doInBackground(String... urls) {  
         CursorFactory factory = null; 
         File ff = new File(Environment.getExternalStorageDirectory()+"/Eisprakseis.sqlite");
         db =SQLiteDatabase.openDatabase(ff.toString(), factory,SQLiteDatabase.NO_LOCALIZED_COLLATORS );
         KtiriaId=getIntent().getStringExtra(DiamEso.ID_EXTRA);
         model=DbFileApodEso.getAllEntos(KtiriaId,db);

         return null;  
     } 

// и в onPostExecute я загружаю записи в намерение через ресторанный адаптер за три секунды, необходимые для определения модели = DbFileApodEso.getAllEntos (KtiriaId, db); пользователь видит диалог

 protected void onPostExecute(Void unused) {  
         Dialog.dismiss();  
         if (Error != null) {  
             Toast.makeText(ApodEsoListaSec.this, Error, Toast.LENGTH_LONG).show();  
         } else {  
             Toast.makeText(ApodEsoListaSec.this, "Ready!" , Toast.LENGTH_SHORT).show();  
         }

         ListView list=(ListView)findViewById(R.id.restaurantsApod);

            startManagingCursor(model);
            //      
            adapter=new RestaurantAdapter(model);
            list.setAdapter(adapter);
            list.setOnItemClickListener(onListClick);

}
0 голосов
/ 12 ноября 2010

Использовать AsyncTask ( ссылка ).

1) Показать ProgressDialog в onPreExecute

2) Выполнить загрузку базы данных в doInBackground

3) Закрыть диалоговое окно в onPostExecute

Пример здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...