Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/212.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 带有RecyclerView的房间数据库视图_Android_Database_Kotlin_Android Room - Fatal编程技术网

Android 带有RecyclerView的房间数据库视图

Android 带有RecyclerView的房间数据库视图,android,database,kotlin,android-room,Android,Database,Kotlin,Android Room,我是Room和Kotlin的新手,我正在尝试构建一个简单的Room数据库,并将其显示在ViewPager中的RecyclerView中 该活动包含一个ViewPager对象,该ViewPager包含一个片段,该片段包含一个RecyclerView: 活动-->查看页面-->片段-->回收视图 我遇到的问题是,当我尝试接收数据库时(在插入之后),我得到了null 代码: 道: 活动: class EventActivity : AppCompatActivity() { private l

我是Room和Kotlin的新手,我正在尝试构建一个简单的Room数据库,并将其显示在ViewPager中的RecyclerView中

该活动包含一个ViewPager对象,该ViewPager包含一个片段,该片段包含一个RecyclerView: 活动-->查看页面-->片段-->回收视图

我遇到的问题是,当我尝试接收数据库时(在插入之后),我得到了null

代码:

道:

活动:

class EventActivity : AppCompatActivity()
{
    private lateinit var viewPager: ViewPager

    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_event)

        viewPager = findViewById(R.id.guests_view_pager)
        val pagerAdapter =  EventPagerAdapter(supportFragmentManager)
        viewPager.adapter = pagerAdapter
    }
}
适配器:

class EventPagerAdapter(fragmentManager: FragmentManager): FragmentPagerAdapter(fragmentManager)
{

    override fun getCount(): Int
    {
        return 1
    }

    override fun getItem(position: Int): Fragment
    {
        return GuestListFragment.newInstance()
    }
}
片段:

class GuestListFragment : Fragment()
{
    private var guestsDataBase: InviterRoomDatabase? = null
    private lateinit var dbWorkerThread: DBWorkerThread

    companion object
    {
        fun newInstance(): GuestListFragment
        {
            val fragment = GuestListFragment()
            return fragment
        }
    }


    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? 
    {

        dbWorkerThread = DBWorkerThread("workerThread")
        dbWorkerThread.start()
        guestsDataBase = InviterRoomDatabase.getDatabase(this.context!!)
        insertGuestToDB(Guest("Joe","052352332",false,0))

        var rootView = inflater.inflate(R.layout.fragment_guest_list, container, false)
        var rv: RecyclerView = rootView.findViewById(R.id.guests_list_recycler_view)
        rv.layoutManager = LinearLayoutManager(context)

        var d = getAllDataFromDB()
        rv.adapter = GuestsRecycleViewAdapter.newInstance(d)

        return rootView
    }


    private fun insertGuestToDB(guest: Guest)
    {
        val task = Runnable {guestsDataBase?.guestsDao()?.insert(guest)}
        dbWorkerThread.postTask(task)
    }

    private fun getAllDataFromDB(): List<Guest>
    {
        var data: List<Guest> = emptyList()
        val task = Runnable { data = guestsDataBase?.guestsDao()?.getAllGuests()!!}

        dbWorkerThread.postTask(task)

        return data
    }
}
class GuestListFragment:Fragment()
{
私有var guestsDataBase:InviterRoomDatabase?=null
私有lateinit var dbWorkerThread:dbWorkerThread
伴星
{
fun newInstance():GuestListFragment
{
val fragment=GuestListFragment()
返回片段
}
}
覆盖创建视图(充气机:布局充气机,容器:ViewGroup?,savedInstanceState:Bundle?):视图?
{
dbWorkerThread=dbWorkerThread(“workerThread”)
dbWorkerThread.start()
guestsDataBase=InviterRoomDatabase.getDatabase(this.context!!)
插入GuestToDB(Guest(“Joe”,“052352332”,假,0))
var rootView=充气机。充气(R.layout.fragment\u guest\u列表,容器,false)
var rv:RecyclerView=rootView.findviewbyd(R.id.guests\u list\u recycler\u视图)
rv.layoutManager=LinearLayoutManager(上下文)
var d=getAllDataFromDB()
rv.adapter=GuestsRecycleViewAdapter.newInstance(d)
返回根视图
}
私人娱乐insertGuestToDB(客人:客人)
{
val task=Runnable{guestsDataBase?.guestsDao()?.insert(guest)}
dbWorkerThread.postTask(任务)
}
private fun getAllDataFromDB():列表
{
变量数据:List=emptyList()
val task=Runnable{data=guestsDataBase?.guestsDao()?.getAllGuests()!!}
dbWorkerThread.postTask(任务)
返回数据
}
}

您需要理解多线程的概念,才能理解代码无法工作的原因。简而言之,您得到的是一个空列表,因为您试图在主线程中获得该列表,而在工作线程上运行的插入和查询尚未完成

我将注释放在代码中以解释执行顺序。注释中的编号为完成顺序:




请注意,这绝对不是解决此问题的最佳方法。这是一个非常常见的问题,有很多不同的解决方案更具可读性、灵活性和可维护性。只是其他解决方案需要更深入的理解,多线程是一个如此广泛的主题,我无法用一个简单的答案解释所有这些问题。不过,我希望您能了解总体思路,并鼓励您探索解决此问题的其他解决方案。

您确定数据库为空吗?当您在INSERT和get函数中使用线程时,可能会得到一个null,因为当您尝试从数据库获取数据时,数据尚未添加..我尝试单独插入并获取所有数据,但我还是得到了空列表对于这种情况,什么是最好的方法?@Itay我想说,使用或的反应式设计可以说是最先进的解决方案。你可能已经很熟悉了。似乎有更多的
Android-room
教程使用其中一个,而不是没有它们的教程。
class EventActivity : AppCompatActivity()
{
    private lateinit var viewPager: ViewPager

    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_event)

        viewPager = findViewById(R.id.guests_view_pager)
        val pagerAdapter =  EventPagerAdapter(supportFragmentManager)
        viewPager.adapter = pagerAdapter
    }
}
class EventPagerAdapter(fragmentManager: FragmentManager): FragmentPagerAdapter(fragmentManager)
{

    override fun getCount(): Int
    {
        return 1
    }

    override fun getItem(position: Int): Fragment
    {
        return GuestListFragment.newInstance()
    }
}
class GuestListFragment : Fragment()
{
    private var guestsDataBase: InviterRoomDatabase? = null
    private lateinit var dbWorkerThread: DBWorkerThread

    companion object
    {
        fun newInstance(): GuestListFragment
        {
            val fragment = GuestListFragment()
            return fragment
        }
    }


    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? 
    {

        dbWorkerThread = DBWorkerThread("workerThread")
        dbWorkerThread.start()
        guestsDataBase = InviterRoomDatabase.getDatabase(this.context!!)
        insertGuestToDB(Guest("Joe","052352332",false,0))

        var rootView = inflater.inflate(R.layout.fragment_guest_list, container, false)
        var rv: RecyclerView = rootView.findViewById(R.id.guests_list_recycler_view)
        rv.layoutManager = LinearLayoutManager(context)

        var d = getAllDataFromDB()
        rv.adapter = GuestsRecycleViewAdapter.newInstance(d)

        return rootView
    }


    private fun insertGuestToDB(guest: Guest)
    {
        val task = Runnable {guestsDataBase?.guestsDao()?.insert(guest)}
        dbWorkerThread.postTask(task)
    }

    private fun getAllDataFromDB(): List<Guest>
    {
        var data: List<Guest> = emptyList()
        val task = Runnable { data = guestsDataBase?.guestsDao()?.getAllGuests()!!}

        dbWorkerThread.postTask(task)

        return data
    }
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? 
{
    // [1] onCreateView starts on main thread.
    dbWorkerThread = DBWorkerThread("workerThread")
    dbWorkerThread.start()
    guestsDataBase = InviterRoomDatabase.getDatabase(this.context!!)
     // [2] calls insertGuestToDB on main thread.
    insertGuestToDB(Guest("Joe","052352332",false,0))

    var rootView = inflater.inflate(R.layout.fragment_guest_list, container, false)
    var rv: RecyclerView = rootView.findViewById(R.id.guests_list_recycler_view)
    rv.layoutManager = LinearLayoutManager(context)

    // [4] calls getAllDataFromDB on main thread.
    var d = getAllDataFromDB()
    // [6] get "d" on main thread. "d" is an empty list. 
    rv.adapter = GuestsRecycleViewAdapter.newInstance(d)

    return rootView
}


private fun insertGuestToDB(guest: Guest)
{
    // [2] insertGuestToDB executed on main thread.
    val task = Runnable {
        guestsDataBase?.guestsDao()?.insert(guest)
        // [7] insertion finished on worker thread.     
    }
    dbWorkerThread.postTask(task)
    // [3] insertGuestToDB finishes on main thread.
}

private fun getAllDataFromDB(): List<Guest>
{
    // [4] getAllDataFromDB on main thread. "data" points to an empty list
    var data: List<Guest> = emptyList()
    val task = Runnable {
        data = guestsDataBase?.guestsDao()?.getAllGuests()!!
        // [8] query finishes on worker thread, but "data" is now lost.
    }
    dbWorkerThread.postTask(task)

    // [5] returns on main thread. "data" still points to an empty list
    return data
}
var rv: RecyclerView

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? 
{

    dbWorkerThread = DBWorkerThread("workerThread")
    dbWorkerThread.start()

    var rootView = inflater.inflate(R.layout.fragment_guest_list, container, false)
    rv= rootView.findViewById(R.id.guests_list_recycler_view)
    rv.layoutManager = LinearLayoutManager(context)

    guestsDataBase = InviterRoomDatabase.getDatabase(this.context!!)
    insertGuestToDbAndUpdateRv(Guest("Joe","052352332",false,0))

    return rootView
}


private fun insertGuestToDbAndUpdateRv(guest: Guest)
{
    val task = Runnable {
        // 1. Insert on a worker thread.
        guestsDataBase?.guestsDao()?.insert(guest)

        // 2. Query on a worker thread.
        var data = guestsDataBase?.guestsDao()?.getAllGuests()!!
        this@GuestListFragment.getActivity().runOnUiThread {
            // 3. Once they are done, update ui on main thread.
            rv.adapter = GuestsRecycleViewAdapter.newInstance(data)
        }
    }
    dbWorkerThread.postTask(task)
}