开发者

Having problems trying to set an adapter inside an AsyncTask

I need to retrieve some huge data from one database when an activity is started. To prevent a user with a frozen window, I decided to run a ProgressDialog while data is being processed.

From OnCreate I call my initDb Class:

new initDb().execute();

And then to do this I have one class inside my activity's class:

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();
    }

}

The real problem happens while setting the adapter:

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);


    }

It always happen to crash on sp.setAdapter(adapter);

Any ideas?

Thank you!


Try taking the finalList as an attribute of your initDb class this way you can populate it on the doInBackground method and then us it on the onPostExecute, like this:

    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();
        }
}


You should call:

sp.setAdapter(adapter);

in main UI thread. For example in onPostExecute() function. Always keep in mind that views (such as ListView) should only be accessed from main thread.


You can't access the UI from other thread than the thread that created the UI. So in AsyncTask, you can't use doInBackground() for this purpose.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜