Возникают проблемы при попытке установить адаптер внутри AsyncTask - PullRequest
0 голосов
/ 09 августа 2011

Мне нужно извлечь огромные данные из одной базы данных, когда начинается действие.Чтобы предотвратить пользователя с замороженным окном, я решил запустить ProgressDialog во время обработки данных.

Из OnCreate я вызываю мой класс initDb:

new initDb (). Execute ();

И затем для этого у меня есть один класс внутри класса моей деятельности:

public class initDb extends AsyncTask<Void, Void, Void> {

    ProgressDialog mDialog = new ProgressDialog(ClientsReg.this);

    @Override
    protected void onPreExecute() {
        mDialog.setMessage("Please wait...");
        mDialog.show();
    }


    @Override
    protected Void doInBackground(Void... voids) {

        opendb();
        listCities();
    return null;


    }

@Override
    protected void onPostExecute(Void unused) {
        // Pass the result data back to the main activity
        mDialog.dismiss();
    }

}

Настоящая проблема возникает при установке адаптера:

private void listCities() {


      mRedrawHandler.sleep(100000);


        c = db.executeSQL("SELECT * FROM RegDB WHERE Reg_Type = 1 AND cad_uzkow = 0 ORDER BY _id DESC");

        //add some list items
        ArrayList<String> finalList = new ArrayList<String>();

        c.moveToFirst();


        while (!c.isAfterLast()){

            finalList.add(c.getString(0) + ")"+ c.getString(5));            
            c.moveToNext();
        }


        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                R.layout.row, R.id.itemShow, finalList);
        sp.setAdapter(adapter);


    }

Всегда случается сбой в sp.setAdapter (адаптере);

Есть идеи?

Спасибо!

Ответы [ 3 ]

0 голосов
/ 09 августа 2011

Вы не можете получить доступ к интерфейсу из другого потока, кроме потока, который создал интерфейс.Поэтому в AsyncTask вы не можете использовать doInBackground () для этой цели.

0 голосов
/ 09 августа 2011

Попробуйте взять finalList в качестве атрибута вашего класса initDb таким образом, чтобы вы могли заполнить его в методе doInBackground, а затем использовать его в onPostExecute, например:

    public class initDb extends AsyncTask<Void, Void, Void> {

    ProgressDialog mDialog = new ProgressDialog(ClientsReg.this);
    ArrayList<String> finalList;

    @Override
    protected void onPreExecute() {
        mDialog.setMessage("Please wait...");
        mDialog.show();
    }


    @Override
    protected Void doInBackground(Void... voids) {

        opendb();
        listCities();
    return null;


    }

@Override
    protected void onPostExecute(Void unused) {
        // Pass the result data back to the main activity

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                R.layout.row, R.id.itemShow, finalList);
        sp.setAdapter(adapter);

        mDialog.dismiss();
    }

private void listCities() {


      mRedrawHandler.sleep(100000);


        c = db.executeSQL("SELECT * FROM RegDB WHERE Reg_Type = 1 AND cad_uzkow = 0 ORDER BY _id DESC");

        //add some list items
        finalList = new ArrayList<String>();

        c.moveToFirst();


        while (!c.isAfterLast()){

            finalList.add(c.getString(0) + ")"+ c.getString(5));            
            c.moveToNext();
        }
}
0 голосов
/ 09 августа 2011

Вам следует позвонить:

sp.setAdapter(adapter);

в основном потоке пользовательского интерфейса. Например, в функции onPostExecute(). Всегда помните, что к представлениям (таким как ListView) следует обращаться только из основного потока.

...