尝试在 AsyncTask 中设置适配器时遇到问题

发布于 2024-11-28 16:29:39 字数 1511 浏览 2 评论 0 原文

当一项活动开始时,我需要从一个数据库检索一些大量数据。为了防止用户窗口冻结,我决定在处理数据时运行 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(adapter); 上崩溃。

有什么想法吗?

谢谢你!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

江挽川 2024-12-05 16:29:39

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

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();
        }
}
生生不灭 2024-12-05 16:29:39

调用:

sp.setAdapter(adapter);

您应该在主 UI 线程中 例如在 onPostExecute() 函数中。请始终记住,视图(例如 ListView)只能从主线程访问。

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.

方圜几里 2024-12-05 16:29:39

您无法从创建 UI 的线程之外的其他线程访问 UI。所以在AsyncTask中,你不能使用doInBackground()来达到这个目的。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文