【问题标题】:Too much for main thread, cannot set from another thread主线程太多,不能从另一个线程设置
【发布时间】:2017-12-10 19:41:50
【问题描述】:

我想在显示布局之前从数据库中创建按钮。我需要这些按钮有一些 onClick 方法,但是我在一个(主)线程上做太多事情时遇到错误。

使用了另一个线程但另一个线程显示错误 - 无法修改来自不同线程的视图

使用 AsyncTask,但将所有工作添加到 onPreExecute()onPostExecute() 并没有解决任何问题,并且在 doInBackground() 中执行此操作(没有意义?)>> 我想渲染按钮但后台进程不能影响主线程

    //get data from database
    DatabaseHelperTables myDb;
    myDb = new DatabaseHelperTables(this);
    tablelist = myDb.getTablesQuery();

    if (tablelist != null) {
        //each button two values [ID,Button_text] in list, therefore i+2
        for (int i = 0; i < tablelist.size(); i = i + 2) {
            final int index = i;

            LinearLayout ll = (LinearLayout) findViewById(R.id.tlacitka);
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            //create button, put inside layer
            final Button button = new Button(this);
            button.setPadding(10, 10, 10, 10);
            button.setText(tablelist.get(i+1));
            ll.addView(button, lp);

            button.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    //pass this to another activity - perform action depending on button ID
                    newActivity.someValue = tablelist.get(index);
                    Intent intent = new Intent(getApplicationContext(), newActivity.class);
                    startActivity(intent);
                }
            });
        }
    }

这一切都在OnCreate(Bundle savedInstanceState)

那么什么是最有效的方法呢?我当时只有两个按钮,但 App 将从 Internet 下载新数据并添加越来越多,具体取决于用户。 我想使用 AsyncTask,但是将上面的代码移动到 onPreExecute()onPostExecute() 得到相同的结果。

编辑: 从数据库中获取数据

 public List<String> getTablesQuery() {
    List<String> query = new ArrayList<>();
    // Select All Query
    String selectQuery = "SELECT * FROM " + TABLE_NAME;
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);
    // looping through all rows and adding to list
    while (cursor.moveToNext()) {
        query.add(cursor.getString(1));
        query.add(cursor.getString(2));
        // Adding contact to list
    }
    cursor.close();
    // return list
    return query;
}

现在在后台 AsyncTask 中运行:

@Override
    protected Void doInBackground(Void... params) {
        DatabaseHelperTables myDb;
        myDb = new DatabaseHelperTables(getApplicationContext());
        //list tablelist defined on the very top of activity
        tablelist = myDb.getTablesQuery();  
        return null;
    }

并在 protected void onPostExecute(Void result) 中使用 onclick 方法设置所有按钮

错误:I/Choreographer:跳过 44 帧!该应用程序可能是 在它的主线程上做太多的工作。

【问题讨论】:

  • stackoverflow.com/help/how-to-ask 你得到的实际错误是什么? “使用了另一个线程,但另一个线程显示错误” - 显示您实际尝试过的内容。什么是“表列表”? getTablesQuery 是什么样的? (这可能是你的问题)
  • 我在主线程错误上做了很多工作,如上所述,`getTablesQuery`很简单地读取整个数据库并将值放入列表中,用光标
  • PS:我的数据库现在由两行组成
  • 你必须在一个单独的线程如 asynctask 上执行 db 操作
  • 已经完成,谢谢,还是同样的问题

标签: java android multithreading button


【解决方案1】:

在后台线程上进行数据库查询,并在 UI 线程上返回结果。此外,您可能一次创建了太多视图(取决于您拥有的数据量)。在这种情况下,我建议使用 RecyclerView,它只会创建尽可能多的视图。

【讨论】:

  • 好吧,我应该在 asynctask 中获取查询,你是对的;但是我也尝试从单个列表创建按钮,但没有从数据库中获取它,仍然需要做太多的工作,我只创建了两个必须适合每个屏幕的按钮:(
  • 更新:在 AsyncTask 中拥有对数据库的所有访问权限,但在创建两个按钮时,主线程上的工作仍然太多......
  • 您可以编辑您的问题并将您用于将查询外包到后台线程的所有代码粘贴到后台线程吗?否则很难提供帮助
猜你喜欢
  • 2022-08-06
  • 2013-03-31
  • 1970-01-01
  • 2021-06-08
  • 1970-01-01
  • 1970-01-01
  • 2012-06-22
  • 2014-06-19
  • 1970-01-01
相关资源
最近更新 更多