无法在可运行的主线程上访问数据库

时间:2018-06-20 13:33:24

标签: android android-room kotlin-android-extensions

房间出现错误:

  

java.lang.IllegalStateException:无法访问主线程上的数据库,因为它可能会长时间锁定UI。

即使我正在创建新线程并在其上运行查询,它也会给我上述错误

我的线程代码:

val thread = Runnable {
            val intent1 = Intent(activity!!, NewOrderActivity::class.java)
            intent1.putExtra("isReview", isReview)
            intent1.putExtra("editClicked", editClicked)
            intent1.putExtra("orderId", orderId)
            intent1.putExtra(ParamsUtils.connected, CommonUtils.isInNetwork(activity))
            intent1.putExtra("orderName", orderName)
            intent1.putExtra("order", Gson().toJson(orderItem))
            intent1.putExtra("groupId", viewModel.getGroupId(orderItem.buyerId))
            Handler().post {
                startActivity(intent1)
                activity!!.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
                activity!!.finish()
            }
        }

        thread.run()

请建议我在哪里,我错了。

修改

我是通过下面的方式知道的,所以请不要对此发表评论。 我不想将活动引用传递给其他类,所以我在同一类中使用线程。

internal class NewOrderAsyncTask(activity: Activity, private val isReview: Boolean, private val editClicked: Boolean, private val orderId: Long, private val orderName: String, private val orderItem: OrderItem, private val dataManager: DataManager) : AsyncTask<Void, Void, String>() {

    //Prevent leak
    private val weakActivity: WeakReference<Activity> = WeakReference(activity)

    override fun doInBackground(vararg params: Void): String {
        return dataManager.getGroupId(orderItem.buyerId)
    }

    override fun onPostExecute(agentsCount: String) {
        val activity = weakActivity.get() ?: return

        val intent1 = Intent(activity!!, NewOrderActivity::class.java)
        intent1.putExtra("isReview", isReview)
        intent1.putExtra("editClicked", editClicked)
        intent1.putExtra("orderId", orderId)
        intent1.putExtra(ParamsUtils.connected, CommonUtils.isInNetwork(activity))
        intent1.putExtra("orderName", orderName)
        intent1.putExtra("order", Gson().toJson(orderItem))
        intent1.putExtra("groupId", agentsCount)
        activity.startActivity(intent1)
        activity.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
        activity.finish()
    }
}
  1. 我的内心困扰是什么?
  2. 当我创建新线程时,为什么会显示错误消息“这是主线程”?

4 个答案:

答案 0 :(得分:1)

改为使用AsyncTask。 例如

class myTask() : AsyncTask<Void, Void, String>() {
    override fun doInBackground(vararg params: Void?): String? {
        // ...
    }

    override fun onPreExecute() {
        super.onPreExecute()
        // ...
    }

    override fun onPostExecute(result: String?) {
        super.onPostExecute(result)
        // ...
    }
}

周围有几个examples

编辑:不了解其余代码,但请尝试在doInBackground部分进行连接,然后将新活动的必需值传递给{{ 1}}遍历其参数

答案 1 :(得分:0)

所有任务,例如从Internet加载内容,从存储中获取数据,都必须在AsyncTask中完成,而不是在UI线程上完成。

创建一个类

public class MyCLass extends AsyncTask

您可以创建一个函数来访问此类中的数据库。在UI线程中,创建该类的对象并调用您创建的函数。互联网上有很多关于AsyncTask的教程。

答案 2 :(得分:0)

您要创建一个新的Thread。相反,您创建了Runnable,因此运行它意味着在主线程上运行。

调用变量“ thread”不会使其成为课程的线程。这会更有意义:

val runnable = Runnable { //runnable code }

也许尝试创建一个新线程并覆盖run方法(java中的示例):

Thread thread = new Thread() {
    @Override
    public void run() {
        //your code
    }
};

thread.start();

答案 3 :(得分:0)

我已将可运行程序包装到线程中:

val thread = Thread(Runnable {
            val intent1 = Intent(activity!!, NewOrderActivity::class.java)
            intent1.putExtra("isReview", isReview)
            intent1.putExtra("editClicked", editClicked)
            intent1.putExtra("orderId", orderId)
            intent1.putExtra(ParamsUtils.connected, CommonUtils.isInNetwork(activity))
            intent1.putExtra("orderName", orderName)
            intent1.putExtra("order", Gson().toJson(orderItem))
            intent1.putExtra("groupId", viewModel.getGroupId(orderItem.buyerId))
            Handler().post {
                startActivity(intent1)
                activity!!.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
                activity!!.finish()
            }
        })

        thread.start()