从 android 上的 asyncTask 获取 java.util.concurrent.RejectedExecutionException

发布于 2024-12-25 02:42:05 字数 10332 浏览 0 评论 0原文

我正在将 sqlite 数据库读入 tableLayout。我不想在单独的线程中执行此操作,而不是在没有用户界面更新的情况下等待很长时间。所以我使用 AsyncTask 来完成一些工作并发布结果。然而,我的列表中只有大约 1/4 的项目真正出现在 TableLayout 上。没有 AsyncTask 也能正常工作。列表中的大多数项目都会抛出错误(我捕获到该错误)java.util.concurrent.RejectedExecutionException。我不知道这是为什么。这是我的代码。

myDB.execSQL("CREATE TABLE IF NOT EXISTS "
                + TableName
                + " (_id INTEGER PRIMARY KEY, filepath TEXT UNIQUE, title TEXT, artist TEXT, album TEXT, time TEXT, playcount NUMERIC);");

        Cursor c = myDB.rawQuery("SELECT * FROM " + TableName, null);         

        c.moveToFirst();
        if (c != null) {
            int color = 0xFFdfe8ea;
            this.startManagingCursor(c);
            // Loop through all Results
            do {
                try{
                    MyAsyncTask aTask = new MyAsyncTask();
                    String[]strings= {c.getString(c.getColumnIndex("title")),c.getString(c.getColumnIndex("artist")),c.getString(c.getColumnIndex("time")),c.getString(c.getColumnIndex("album")),""+color};
                    aTask.execute(strings);
                }catch(Exception e){
                    Log.w("****", e);
                }
        if (color == 0xFFdfe8ea) {
                    color = 0xFFf2f8fa;
                } else {
                    color = 0xFFdfe8ea;
                }
            } while (c.moveToNext());
        }

    } catch (SQLException e) {
        Log.e("****", e.toString());
    } finally {
        if (myDB != null) {
            myDB.close();
        }
    }

这是 AsyncTask

class MyAsyncTask extends AsyncTask<String, Void, View> {
    @Override
    protected View doInBackground(String... params) {
        int color = Integer.parseInt(params[4]);

        TableRow tr = new TableRow(MainActivity.this);
        tr.setLayoutParams(new LayoutParams(
                LayoutParams.FILL_PARENT,
                LayoutParams.WRAP_CONTENT));

        TextView space = new TextView(MainActivity.this);
        space.setText("");
        space.setBackgroundColor(color); //0xFFf2f8fa alternating
        space.setSingleLine();
        space.setPadding(2, 2, 2, 2);
        space.setGravity(Gravity.LEFT);
        space.setTextColor(0xFF000000);
        space.setLayoutParams(new LayoutParams(
                findViewById(R.id.spaceColumn).getWidth(),
                LayoutParams.WRAP_CONTENT));

        /* Create a Button to be the row-content. */
        TextView title = new TextView(MainActivity.this);
        title.setText(params[0]);
        title.setBackgroundColor(color); //0xFFf2f8fa alternating
        title.setSingleLine();
        title.setPadding(2, 2, 2, 2);
        title.setGravity(Gravity.LEFT);
        title.setTextColor(0xFF000000);
        title.setEllipsize(TruncateAt.END);
        title.setLayoutParams(new LayoutParams(
                0,
                LayoutParams.WRAP_CONTENT, 1));

        /* Create a Button to be the row-content. */
        TextView artist = new TextView(MainActivity.this);
        artist.setText(params[1]);
        artist.setBackgroundColor(color); //0xFFf2f8fa alternating
        artist.setSingleLine();
        artist.setPadding(2, 2, 2, 2);
        artist.setGravity(Gravity.LEFT);
        artist.setTextColor(0xFF000000);
        artist.setEllipsize(TruncateAt.END);
        artist.setLayoutParams(new LayoutParams(
                0,
                LayoutParams.WRAP_CONTENT, 1));

        /* Create a Button to be the row-content. */
        TextView time = new TextView(MainActivity.this);
        time.setText(params[2]);
        time.setBackgroundColor(color); //0xFFf2f8fa alternating
        time.setSingleLine();
        time.setPadding(2, 2, 2, 2);
        time.setGravity(Gravity.LEFT);
        time.setTextColor(0xFF000000);
        time.setLayoutParams(new LayoutParams(
                findViewById(R.id.timeColumn).getWidth(),
                LayoutParams.WRAP_CONTENT));

        /* Create a Button to be the row-content. */
        TextView album = new TextView(MainActivity.this);
        album.setText(params[3]);
        album.setBackgroundColor(color); //0xFFf2f8fa alternating
        album.setSingleLine();
        album.setPadding(2, 2, 2, 2);
        album.setGravity(Gravity.LEFT);
        album.setTextColor(0xFF000000);
        album.setEllipsize(TruncateAt.END);
        album.setLayoutParams(new LayoutParams(
                0,
                LayoutParams.WRAP_CONTENT, 1));

        /* Add Button to row. */
        tr.addView(space);
        tr.addView(title);
        tr.addView(artist);
        tr.addView(time);
        tr.addView(album);

        /* Add row to TableLayout. */
        return tr;
    }

    @Override
    protected void onPostExecute(View tr) {
        ((TableLayout) findViewById(R.id.tableLayout)).addView(tr, new TableLayout.LayoutParams(
                        LayoutParams.FILL_PARENT,
                        LayoutParams.WRAP_CONTENT));
    }

    @Override
    protected void onPreExecute() {
    }
 }

供参考,这就是我修复它的方法。

class MyAsyncTask extends AsyncTask<Void, Song, Void> {

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

        SQLiteDatabase myDB = openOrCreateDatabase("DatabaseName", MODE_PRIVATE, null);
        String TableName = "songs";

        myDB.execSQL("CREATE TABLE IF NOT EXISTS "
                + TableName
                + " (_id INTEGER PRIMARY KEY, filepath TEXT UNIQUE, title TEXT, artist TEXT, album TEXT, time TEXT, playcount NUMERIC);");

        Cursor c = myDB.rawQuery("SELECT * FROM " + TableName, null);

        c.moveToFirst();
        int filepathIndex=c.getColumnIndex("filepath");
        int titleIndex=c.getColumnIndex("title");
        int artistIndex=c.getColumnIndex("artist");
        int albumIndex=c.getColumnIndex("album");
        int timeIndex=c.getColumnIndex("time");
        int playcountIndex=c.getColumnIndex("playcount");

        if (c != null) {
            int color = 0xFFdfe8ea;
         //   this.startManagingCursor(c);
            // Loop through all Results
            do {
                Song song = new Song(c.getString(filepathIndex),c.getString(titleIndex),c.getString(artistIndex),c.getString(albumIndex),c.getString(timeIndex),c.getInt(playcountIndex),color);
                // Add to song the data from your cursor
                publishProgress(song);

                if (color == 0xFFdfe8ea) {
                    color = 0xFFf2f8fa;
                } else {
                    color = 0xFFdfe8ea;
                }
            } while (c.moveToNext());
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void item) {
    }

    @Override
    protected void onPreExecute() {
    }

    @Override
    protected void onProgressUpdate(Song... items) {
        for (Song song : items) {
            TableRow tr = new TableRow(MainActivity.this);
            tr.setLayoutParams(new LayoutParams(
                    LayoutParams.FILL_PARENT,
                    LayoutParams.WRAP_CONTENT));

            TextView space = new TextView(MainActivity.this);
            space.setText("");
            space.setBackgroundColor(song.color); //0xFFf2f8fa alternating
            space.setSingleLine();
            space.setPadding(2, 2, 2, 2);
            space.setGravity(Gravity.LEFT);
            space.setTextColor(0xFF000000);
            space.setLayoutParams(new LayoutParams(
                    findViewById(R.id.spaceColumn).getWidth(),
                    LayoutParams.WRAP_CONTENT));

            /* Create a Button to be the row-content. */
            TextView title = new TextView(MainActivity.this);
            title.setText(song.title);
            title.setBackgroundColor(song.color); //0xFFf2f8fa alternating
            title.setSingleLine();
            title.setPadding(2, 2, 2, 2);
            title.setGravity(Gravity.LEFT);
            title.setTextColor(0xFF000000);
            title.setEllipsize(TruncateAt.END);
            title.setLayoutParams(new LayoutParams(
                    0,
                    LayoutParams.WRAP_CONTENT, 1));

            /* Create a Button to be the row-content. */
            TextView artist = new TextView(MainActivity.this);
            artist.setText(song.artist);
            artist.setBackgroundColor(song.color); //0xFFf2f8fa alternating
            artist.setSingleLine();
            artist.setPadding(2, 2, 2, 2);
            artist.setGravity(Gravity.LEFT);
            artist.setTextColor(0xFF000000);
            artist.setEllipsize(TruncateAt.END);
            artist.setLayoutParams(new LayoutParams(
                    0,
                    LayoutParams.WRAP_CONTENT, 1));

            /* Create a Button to be the row-content. */
            TextView time = new TextView(MainActivity.this);
            time.setText(song.time);
            time.setBackgroundColor(song.color); //0xFFf2f8fa alternating
            time.setSingleLine();
            time.setPadding(2, 2, 2, 2);
            time.setGravity(Gravity.LEFT);
            time.setTextColor(0xFF000000);
            time.setLayoutParams(new LayoutParams(
                    findViewById(R.id.timeColumn).getWidth(),
                    LayoutParams.WRAP_CONTENT));

            /* Create a Button to be the row-content. */
            TextView album = new TextView(MainActivity.this);
            album.setText(song.album);
            album.setBackgroundColor(song.color); //0xFFf2f8fa alternating
            album.setSingleLine();
            album.setPadding(2, 2, 2, 2);
            album.setGravity(Gravity.LEFT);
            album.setTextColor(0xFF000000);
            album.setEllipsize(TruncateAt.END);
            album.setLayoutParams(new LayoutParams(
                    0,
                    LayoutParams.WRAP_CONTENT, 1));

            /* Add Button to row. */
            tr.addView(space);
            tr.addView(title);
            tr.addView(artist);
            tr.addView(time);
            tr.addView(album);

            // Add the row to the table
            ((TableLayout) findViewById(R.id.tableLayout)).addView(tr, new TableLayout.LayoutParams(
                    LayoutParams.FILL_PARENT,
                    LayoutParams.WRAP_CONTENT));
        }
    }
}

I am reading a sqlite database into a tableLayout. I wan't to do this in a seperate thread instead of having a long wait with no ui updates. So I used an AsyncTask to do some of the work and publish the results. However only about 1/4th of the item in my list actually make it on to the TableLayout. It works fine without the AsyncTask. Most of the items on the list throw an error (which I caught) java.util.concurrent.RejectedExecutionException. I'm not sure why this is. Here is my code.

myDB.execSQL("CREATE TABLE IF NOT EXISTS "
                + TableName
                + " (_id INTEGER PRIMARY KEY, filepath TEXT UNIQUE, title TEXT, artist TEXT, album TEXT, time TEXT, playcount NUMERIC);");

        Cursor c = myDB.rawQuery("SELECT * FROM " + TableName, null);         

        c.moveToFirst();
        if (c != null) {
            int color = 0xFFdfe8ea;
            this.startManagingCursor(c);
            // Loop through all Results
            do {
                try{
                    MyAsyncTask aTask = new MyAsyncTask();
                    String[]strings= {c.getString(c.getColumnIndex("title")),c.getString(c.getColumnIndex("artist")),c.getString(c.getColumnIndex("time")),c.getString(c.getColumnIndex("album")),""+color};
                    aTask.execute(strings);
                }catch(Exception e){
                    Log.w("****", e);
                }
        if (color == 0xFFdfe8ea) {
                    color = 0xFFf2f8fa;
                } else {
                    color = 0xFFdfe8ea;
                }
            } while (c.moveToNext());
        }

    } catch (SQLException e) {
        Log.e("****", e.toString());
    } finally {
        if (myDB != null) {
            myDB.close();
        }
    }

and here is the AsyncTask

class MyAsyncTask extends AsyncTask<String, Void, View> {
    @Override
    protected View doInBackground(String... params) {
        int color = Integer.parseInt(params[4]);

        TableRow tr = new TableRow(MainActivity.this);
        tr.setLayoutParams(new LayoutParams(
                LayoutParams.FILL_PARENT,
                LayoutParams.WRAP_CONTENT));

        TextView space = new TextView(MainActivity.this);
        space.setText("");
        space.setBackgroundColor(color); //0xFFf2f8fa alternating
        space.setSingleLine();
        space.setPadding(2, 2, 2, 2);
        space.setGravity(Gravity.LEFT);
        space.setTextColor(0xFF000000);
        space.setLayoutParams(new LayoutParams(
                findViewById(R.id.spaceColumn).getWidth(),
                LayoutParams.WRAP_CONTENT));

        /* Create a Button to be the row-content. */
        TextView title = new TextView(MainActivity.this);
        title.setText(params[0]);
        title.setBackgroundColor(color); //0xFFf2f8fa alternating
        title.setSingleLine();
        title.setPadding(2, 2, 2, 2);
        title.setGravity(Gravity.LEFT);
        title.setTextColor(0xFF000000);
        title.setEllipsize(TruncateAt.END);
        title.setLayoutParams(new LayoutParams(
                0,
                LayoutParams.WRAP_CONTENT, 1));

        /* Create a Button to be the row-content. */
        TextView artist = new TextView(MainActivity.this);
        artist.setText(params[1]);
        artist.setBackgroundColor(color); //0xFFf2f8fa alternating
        artist.setSingleLine();
        artist.setPadding(2, 2, 2, 2);
        artist.setGravity(Gravity.LEFT);
        artist.setTextColor(0xFF000000);
        artist.setEllipsize(TruncateAt.END);
        artist.setLayoutParams(new LayoutParams(
                0,
                LayoutParams.WRAP_CONTENT, 1));

        /* Create a Button to be the row-content. */
        TextView time = new TextView(MainActivity.this);
        time.setText(params[2]);
        time.setBackgroundColor(color); //0xFFf2f8fa alternating
        time.setSingleLine();
        time.setPadding(2, 2, 2, 2);
        time.setGravity(Gravity.LEFT);
        time.setTextColor(0xFF000000);
        time.setLayoutParams(new LayoutParams(
                findViewById(R.id.timeColumn).getWidth(),
                LayoutParams.WRAP_CONTENT));

        /* Create a Button to be the row-content. */
        TextView album = new TextView(MainActivity.this);
        album.setText(params[3]);
        album.setBackgroundColor(color); //0xFFf2f8fa alternating
        album.setSingleLine();
        album.setPadding(2, 2, 2, 2);
        album.setGravity(Gravity.LEFT);
        album.setTextColor(0xFF000000);
        album.setEllipsize(TruncateAt.END);
        album.setLayoutParams(new LayoutParams(
                0,
                LayoutParams.WRAP_CONTENT, 1));

        /* Add Button to row. */
        tr.addView(space);
        tr.addView(title);
        tr.addView(artist);
        tr.addView(time);
        tr.addView(album);

        /* Add row to TableLayout. */
        return tr;
    }

    @Override
    protected void onPostExecute(View tr) {
        ((TableLayout) findViewById(R.id.tableLayout)).addView(tr, new TableLayout.LayoutParams(
                        LayoutParams.FILL_PARENT,
                        LayoutParams.WRAP_CONTENT));
    }

    @Override
    protected void onPreExecute() {
    }
 }

For reference this is how I fixed it.

class MyAsyncTask extends AsyncTask<Void, Song, Void> {

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

        SQLiteDatabase myDB = openOrCreateDatabase("DatabaseName", MODE_PRIVATE, null);
        String TableName = "songs";

        myDB.execSQL("CREATE TABLE IF NOT EXISTS "
                + TableName
                + " (_id INTEGER PRIMARY KEY, filepath TEXT UNIQUE, title TEXT, artist TEXT, album TEXT, time TEXT, playcount NUMERIC);");

        Cursor c = myDB.rawQuery("SELECT * FROM " + TableName, null);

        c.moveToFirst();
        int filepathIndex=c.getColumnIndex("filepath");
        int titleIndex=c.getColumnIndex("title");
        int artistIndex=c.getColumnIndex("artist");
        int albumIndex=c.getColumnIndex("album");
        int timeIndex=c.getColumnIndex("time");
        int playcountIndex=c.getColumnIndex("playcount");

        if (c != null) {
            int color = 0xFFdfe8ea;
         //   this.startManagingCursor(c);
            // Loop through all Results
            do {
                Song song = new Song(c.getString(filepathIndex),c.getString(titleIndex),c.getString(artistIndex),c.getString(albumIndex),c.getString(timeIndex),c.getInt(playcountIndex),color);
                // Add to song the data from your cursor
                publishProgress(song);

                if (color == 0xFFdfe8ea) {
                    color = 0xFFf2f8fa;
                } else {
                    color = 0xFFdfe8ea;
                }
            } while (c.moveToNext());
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void item) {
    }

    @Override
    protected void onPreExecute() {
    }

    @Override
    protected void onProgressUpdate(Song... items) {
        for (Song song : items) {
            TableRow tr = new TableRow(MainActivity.this);
            tr.setLayoutParams(new LayoutParams(
                    LayoutParams.FILL_PARENT,
                    LayoutParams.WRAP_CONTENT));

            TextView space = new TextView(MainActivity.this);
            space.setText("");
            space.setBackgroundColor(song.color); //0xFFf2f8fa alternating
            space.setSingleLine();
            space.setPadding(2, 2, 2, 2);
            space.setGravity(Gravity.LEFT);
            space.setTextColor(0xFF000000);
            space.setLayoutParams(new LayoutParams(
                    findViewById(R.id.spaceColumn).getWidth(),
                    LayoutParams.WRAP_CONTENT));

            /* Create a Button to be the row-content. */
            TextView title = new TextView(MainActivity.this);
            title.setText(song.title);
            title.setBackgroundColor(song.color); //0xFFf2f8fa alternating
            title.setSingleLine();
            title.setPadding(2, 2, 2, 2);
            title.setGravity(Gravity.LEFT);
            title.setTextColor(0xFF000000);
            title.setEllipsize(TruncateAt.END);
            title.setLayoutParams(new LayoutParams(
                    0,
                    LayoutParams.WRAP_CONTENT, 1));

            /* Create a Button to be the row-content. */
            TextView artist = new TextView(MainActivity.this);
            artist.setText(song.artist);
            artist.setBackgroundColor(song.color); //0xFFf2f8fa alternating
            artist.setSingleLine();
            artist.setPadding(2, 2, 2, 2);
            artist.setGravity(Gravity.LEFT);
            artist.setTextColor(0xFF000000);
            artist.setEllipsize(TruncateAt.END);
            artist.setLayoutParams(new LayoutParams(
                    0,
                    LayoutParams.WRAP_CONTENT, 1));

            /* Create a Button to be the row-content. */
            TextView time = new TextView(MainActivity.this);
            time.setText(song.time);
            time.setBackgroundColor(song.color); //0xFFf2f8fa alternating
            time.setSingleLine();
            time.setPadding(2, 2, 2, 2);
            time.setGravity(Gravity.LEFT);
            time.setTextColor(0xFF000000);
            time.setLayoutParams(new LayoutParams(
                    findViewById(R.id.timeColumn).getWidth(),
                    LayoutParams.WRAP_CONTENT));

            /* Create a Button to be the row-content. */
            TextView album = new TextView(MainActivity.this);
            album.setText(song.album);
            album.setBackgroundColor(song.color); //0xFFf2f8fa alternating
            album.setSingleLine();
            album.setPadding(2, 2, 2, 2);
            album.setGravity(Gravity.LEFT);
            album.setTextColor(0xFF000000);
            album.setEllipsize(TruncateAt.END);
            album.setLayoutParams(new LayoutParams(
                    0,
                    LayoutParams.WRAP_CONTENT, 1));

            /* Add Button to row. */
            tr.addView(space);
            tr.addView(title);
            tr.addView(artist);
            tr.addView(time);
            tr.addView(album);

            // Add the row to the table
            ((TableLayout) findViewById(R.id.tableLayout)).addView(tr, new TableLayout.LayoutParams(
                    LayoutParams.FILL_PARENT,
                    LayoutParams.WRAP_CONTENT));
        }
    }
}

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

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

发布评论

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

评论(3

一曲爱恨情仇 2025-01-01 02:42:05

您看到此 RejectedExceutionException 的原因几乎可以肯定是因为您提交了太多请求。

我刚刚进入 AsyncTask 的代码,我注意到:

private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final int KEEP_ALIVE = 1;

private static final BlockingQueue<Runnable> sPoolWorkQueue =
      new LinkedBlockingQueue<Runnable>(10);

/**
* An {@link Executor} that can be used to execute tasks in parallel.
*/
    public static final Executor THREAD_POOL_EXECUTOR
            = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
                    TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

这将构建一个有界的 LinkedBlockingQueue。边界最多 10 个元素。这
我看到的 MAXIMUM_POOL_SIZE 是 128(这意味着如果需要,执行器将最多创建 128 个线程)。

一旦超过 128 个线程并提交到队列深度为 10 的新 MyTask 实例,您将收到 RejectedExecutionException。当所有可用线程饱和并且队列上没有更多空间时,会引发此异常。

您可以通过在 RejectedExecution 发生时获取线程转储来轻松确认这一点。

基本上,您可以在任何特定时间提交 138 个 MyTask,但一旦您同时提交 139 个以上(不在应用程序的生命周期内),您将遇到此问题

编辑:< /em> 我详细检查了代码,最新版本(实际上是 2011 年 1 月 16 日以来)这个错误应该永远不会发生。

对于任何旧版本,您都会遇到这个 问题

简而言之,如果您升级版本,这个问题就会消失,但是每个任务将串行执行,而不是同时执行。

The reason you are seeing this RejectedExceutionException is almost certainly because you are submitting too many requests.

I just went into the code of AsyncTask and I noticed:

private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final int KEEP_ALIVE = 1;

private static final BlockingQueue<Runnable> sPoolWorkQueue =
      new LinkedBlockingQueue<Runnable>(10);

/**
* An {@link Executor} that can be used to execute tasks in parallel.
*/
    public static final Executor THREAD_POOL_EXECUTOR
            = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
                    TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

That will build a bounded LinkedBlockingQueue. Up to 10 elements for the bound. The
MAXIMUM_POOL_SIZE I saw was 128 (which means if needed the Executor will create 128 threads at most).

Once you exceed the 128 thread and submit to a new MyTask instance with a queue depth of 10 you will get a RejectedExecutionException. This exception is thrown when you saturate all available threads and there is no more room on the queue.

You can easily confirm this by getting a thread-dump when the RejectedExecution occurs.

Basically, you can submit 138 MyTask's at any particular time but once you submit 139+ at the same time (not within the life time of the app) you will run into this issue

Edit: I went through the code more, and the most recent version (actually since Jan 16, 2011) this error should never happen.

With any version older then that you will run into this issue.

In short, if you upgrade you version this issue will go away, however each task will be executed serially and not concurrently.

欢你一世 2025-01-01 02:42:05

如果您想使用 AsyncTask 来执行此操作,请考虑使用 publishProgress(),这样每个项目都会在从数据库中获取时添加。这样:

注意:考虑 Song 是一个具有 namealbumartist 的类code> 和 time 属性。

class MyAsyncTask extends AsyncTask<Void, Song, Void> {
    @Override
    protected Void doInBackground(Void... params) {
        myDB.execSQL("CREATE TABLE IF NOT EXISTS "
            + TableName
            + " (_id INTEGER PRIMARY KEY, filepath TEXT UNIQUE, title TEXT, artist TEXT, album TEXT, time TEXT, playcount NUMERIC);");

        Cursor c = myDB.rawQuery("SELECT * FROM " + TableName, null);         

        c.moveToFirst();
        if (c != null) {
            int color = 0xFFdfe8ea;
            this.startManagingCursor(c);
            // Loop through all Results
            do {
                Song song = new Song();
                // Add to song the data from your cursor
                publishProgress(song);
            } while (c.moveToNext());
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void item) {
    }

    @Override
    protected void onPreExecute() {
    }       

    @Override
    protected void onProgressUpdate(Song... items) {
        for (Song song : items) {    
            TableRow tr = new TableRow(MainActivity.this);
            tr.setLayoutParams(new LayoutParams(
                    LayoutParams.FILL_PARENT,
                    LayoutParams.WRAP_CONTENT));

            TextView space = new TextView(MainActivity.this);
            space.setText("");
            space.setBackgroundColor(color); //0xFFf2f8fa alternating
            space.setSingleLine();
            space.setPadding(2, 2, 2, 2);
            space.setGravity(Gravity.LEFT);
            space.setTextColor(0xFF000000);
            space.setLayoutParams(new LayoutParams(
                    findViewById(R.id.spaceColumn).getWidth(),
                    LayoutParams.WRAP_CONTENT));

            /* Create a Button to be the row-content. */
            TextView title = new TextView(MainActivity.this);
            title.setText(song.getTitle());
            title.setBackgroundColor(color); //0xFFf2f8fa alternating
            title.setSingleLine();
            title.setPadding(2, 2, 2, 2);
            title.setGravity(Gravity.LEFT);
            title.setTextColor(0xFF000000);
            title.setEllipsize(TruncateAt.END);
            title.setLayoutParams(new LayoutParams(
                    0,
                    LayoutParams.WRAP_CONTENT, 1));

            /* Create a Button to be the row-content. */
            TextView artist = new TextView(MainActivity.this);
            artist.setText(song.getArtist());
            artist.setBackgroundColor(color); //0xFFf2f8fa alternating
            artist.setSingleLine();
            artist.setPadding(2, 2, 2, 2);
            artist.setGravity(Gravity.LEFT);
            artist.setTextColor(0xFF000000);
            artist.setEllipsize(TruncateAt.END);
            artist.setLayoutParams(new LayoutParams(
                    0,
                    LayoutParams.WRAP_CONTENT, 1));

            /* Create a Button to be the row-content. */
            TextView time = new TextView(MainActivity.this);
            time.setText(song.getTime());
            time.setBackgroundColor(color); //0xFFf2f8fa alternating
            time.setSingleLine();
            time.setPadding(2, 2, 2, 2);
            time.setGravity(Gravity.LEFT);
            time.setTextColor(0xFF000000);
            time.setLayoutParams(new LayoutParams(
                    findViewById(R.id.timeColumn).getWidth(),
                    LayoutParams.WRAP_CONTENT));

            /* Create a Button to be the row-content. */
            TextView album = new TextView(MainActivity.this);
            album.setText(song.getAlbum());
            album.setBackgroundColor(color); //0xFFf2f8fa alternating
            album.setSingleLine();
            album.setPadding(2, 2, 2, 2);
            album.setGravity(Gravity.LEFT);
            album.setTextColor(0xFF000000);
            album.setEllipsize(TruncateAt.END);
            album.setLayoutParams(new LayoutParams(
                    0,
                    LayoutParams.WRAP_CONTENT, 1));

            /* Add Button to row. */
            tr.addView(space);
            tr.addView(title);
            tr.addView(artist);
            tr.addView(time);
            tr.addView(album);

            // Add the row to the table
            ((TableLayout) findViewById(R.id.tableLayout)).addView(tr, new TableLayout.LayoutParams(
                            LayoutParams.FILL_PARENT,
                            LayoutParams.WRAP_CONTENT));
        }
    }
 }

我相信您错误地理解了 AsyncTask 背后的概念,我强烈建议您重新阅读 Android 上的文档开发人员这个概念有点难以理解,但当你这样做时却非常强大。正如 Romain Guy 对您的答案的评论,您只能在 onPreExecute()、onProgressUpdate() 和 onPostExecute() 方法上执行 UI 代码。

If you want to do it using an AsyncTask, consider using publishProgress(), that way each item will be added as it is fetched from the database. This way:

NOTE: Consider that Song is a class with name, album, artist and time attributes.

class MyAsyncTask extends AsyncTask<Void, Song, Void> {
    @Override
    protected Void doInBackground(Void... params) {
        myDB.execSQL("CREATE TABLE IF NOT EXISTS "
            + TableName
            + " (_id INTEGER PRIMARY KEY, filepath TEXT UNIQUE, title TEXT, artist TEXT, album TEXT, time TEXT, playcount NUMERIC);");

        Cursor c = myDB.rawQuery("SELECT * FROM " + TableName, null);         

        c.moveToFirst();
        if (c != null) {
            int color = 0xFFdfe8ea;
            this.startManagingCursor(c);
            // Loop through all Results
            do {
                Song song = new Song();
                // Add to song the data from your cursor
                publishProgress(song);
            } while (c.moveToNext());
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void item) {
    }

    @Override
    protected void onPreExecute() {
    }       

    @Override
    protected void onProgressUpdate(Song... items) {
        for (Song song : items) {    
            TableRow tr = new TableRow(MainActivity.this);
            tr.setLayoutParams(new LayoutParams(
                    LayoutParams.FILL_PARENT,
                    LayoutParams.WRAP_CONTENT));

            TextView space = new TextView(MainActivity.this);
            space.setText("");
            space.setBackgroundColor(color); //0xFFf2f8fa alternating
            space.setSingleLine();
            space.setPadding(2, 2, 2, 2);
            space.setGravity(Gravity.LEFT);
            space.setTextColor(0xFF000000);
            space.setLayoutParams(new LayoutParams(
                    findViewById(R.id.spaceColumn).getWidth(),
                    LayoutParams.WRAP_CONTENT));

            /* Create a Button to be the row-content. */
            TextView title = new TextView(MainActivity.this);
            title.setText(song.getTitle());
            title.setBackgroundColor(color); //0xFFf2f8fa alternating
            title.setSingleLine();
            title.setPadding(2, 2, 2, 2);
            title.setGravity(Gravity.LEFT);
            title.setTextColor(0xFF000000);
            title.setEllipsize(TruncateAt.END);
            title.setLayoutParams(new LayoutParams(
                    0,
                    LayoutParams.WRAP_CONTENT, 1));

            /* Create a Button to be the row-content. */
            TextView artist = new TextView(MainActivity.this);
            artist.setText(song.getArtist());
            artist.setBackgroundColor(color); //0xFFf2f8fa alternating
            artist.setSingleLine();
            artist.setPadding(2, 2, 2, 2);
            artist.setGravity(Gravity.LEFT);
            artist.setTextColor(0xFF000000);
            artist.setEllipsize(TruncateAt.END);
            artist.setLayoutParams(new LayoutParams(
                    0,
                    LayoutParams.WRAP_CONTENT, 1));

            /* Create a Button to be the row-content. */
            TextView time = new TextView(MainActivity.this);
            time.setText(song.getTime());
            time.setBackgroundColor(color); //0xFFf2f8fa alternating
            time.setSingleLine();
            time.setPadding(2, 2, 2, 2);
            time.setGravity(Gravity.LEFT);
            time.setTextColor(0xFF000000);
            time.setLayoutParams(new LayoutParams(
                    findViewById(R.id.timeColumn).getWidth(),
                    LayoutParams.WRAP_CONTENT));

            /* Create a Button to be the row-content. */
            TextView album = new TextView(MainActivity.this);
            album.setText(song.getAlbum());
            album.setBackgroundColor(color); //0xFFf2f8fa alternating
            album.setSingleLine();
            album.setPadding(2, 2, 2, 2);
            album.setGravity(Gravity.LEFT);
            album.setTextColor(0xFF000000);
            album.setEllipsize(TruncateAt.END);
            album.setLayoutParams(new LayoutParams(
                    0,
                    LayoutParams.WRAP_CONTENT, 1));

            /* Add Button to row. */
            tr.addView(space);
            tr.addView(title);
            tr.addView(artist);
            tr.addView(time);
            tr.addView(album);

            // Add the row to the table
            ((TableLayout) findViewById(R.id.tableLayout)).addView(tr, new TableLayout.LayoutParams(
                            LayoutParams.FILL_PARENT,
                            LayoutParams.WRAP_CONTENT));
        }
    }
 }

I believe you understood the concept behind AsyncTask wrongly, I strongly suggest you reread its documentation at Android Developers as its concept is a bit tricky to understand but very powerfull when you do so. As Romain Guy commented on your answer you can only execute UI code on the onPreExecute(), onProgressUpdate() and onPostExecute() methods.

东京女 2025-01-01 02:42:05

我认为您不需要为此创建一个 AsyncTask。您没有从网络获取任何内容或下载图像。它只是标准加载。

我会用“limit”限制 SQL 中的结果。

另外,您是在适配器内执行此操作吗?因为我认为您正在将所有内容添加到列表中,您应该在布局中创建一个列表视图并设置一个适配器。也许扩展 BaseAdapter。

每个适配器都有一个名为 getView 的便捷方法,该方法仅在可见时才会被调用,并且应该有助于解决您的问题。

这是适配器的示例:

public class MyAdapter extends BaseAdapter {

    private Context context = null;
    private Cursor cursor;

    public MyAdapter(Context context){

        this.context = context;     
        SQLiteDatabase db = DatabaseHelper.getInstance(context).getReadableDatabase();              
        this.cursor = db.query("YOUR QUERY");

    }

    @Override
    public int getCount() {
        return this.cursor.getCount();
    }


    public Cursor getCursor() {
        return cursor;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        LinearLayout row;

        try {           
        cursor.moveToPosition(position);

        if (convertView == null) {      
            row = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.myRowLayout, parent, false);
            } else {
            row = (LinearLayout) convertView;
            }

        TextView name = (TextView) row.findViewById(R.id.myLayoutId);
        name.setText(cursor.getString(cursor.getColumnIndex("your column")));

        } catch (Exception e) {
            row = null;
            Log.e(LOG_TAG, "" + e.getMessage());
            e.printStackTrace();
        }

        return row;

    }

    @Override
    public MoneyCurrency getItem(int position) {        
        this.cursor.moveToPosition(position);
        long id = this.cursor.getLong(this.cursor.getColumnIndex("your column id")); 
        return new Object.read(id, context, null); //Return whatever you want to show in that row. This is used if you want to use onClick listeners or menus
    }

    @Override
    public long getItemId(int position) {
        this.cursor.moveToPosition(position);
        return this.cursor.getLong(this.cursor.getColumnIndex("your id column"));
    }



    }

I dont think you need to create one AsyncTask for that. You are not fetching anything from the network or downloading images. Its just standard loading.

I would limit the result in the SQL with 'limit'.

Also, you are doing that inside an adapter right? Because I think you are adding everything to the list, where you should create a listview in your layout and set an Adapter. Maybe extending BaseAdapter.

Every adapter has a convenient method called getView that will get called only when it is visible and should help with your problem.

This is an example of an adapter:

public class MyAdapter extends BaseAdapter {

    private Context context = null;
    private Cursor cursor;

    public MyAdapter(Context context){

        this.context = context;     
        SQLiteDatabase db = DatabaseHelper.getInstance(context).getReadableDatabase();              
        this.cursor = db.query("YOUR QUERY");

    }

    @Override
    public int getCount() {
        return this.cursor.getCount();
    }


    public Cursor getCursor() {
        return cursor;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        LinearLayout row;

        try {           
        cursor.moveToPosition(position);

        if (convertView == null) {      
            row = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.myRowLayout, parent, false);
            } else {
            row = (LinearLayout) convertView;
            }

        TextView name = (TextView) row.findViewById(R.id.myLayoutId);
        name.setText(cursor.getString(cursor.getColumnIndex("your column")));

        } catch (Exception e) {
            row = null;
            Log.e(LOG_TAG, "" + e.getMessage());
            e.printStackTrace();
        }

        return row;

    }

    @Override
    public MoneyCurrency getItem(int position) {        
        this.cursor.moveToPosition(position);
        long id = this.cursor.getLong(this.cursor.getColumnIndex("your column id")); 
        return new Object.read(id, context, null); //Return whatever you want to show in that row. This is used if you want to use onClick listeners or menus
    }

    @Override
    public long getItemId(int position) {
        this.cursor.moveToPosition(position);
        return this.cursor.getLong(this.cursor.getColumnIndex("your id column"));
    }



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