想在 android studio kotlin 中为列表视图上的 setOnItemClickListener 创建新线程,以通过从数据库中获取数据来打开新的 activity

want to create new thread in android studio kotlin for setOnItemClickListener on listview to open new activity by taking data from database

想在 android studio kotlin 中为列表视图上的 setOnItemClickListener 创建新线程,以通过从数据库中获取数据来打开新的 activity。 我在主线程上执行此操作,这使我的应用程序冻结,有时它需要超过 2、3 次点击列表项才能打开我点击的项目的相应 activity。

package com.example.countriescapitals_continentwise

import android.content.Intent
import android.os.AsyncTask
import android.os.Bundle
import android.text.PrecomputedText
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ListView
import android.widget.ProgressBar
import android.widget.SearchView
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import javax.xml.transform.Result

// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

/**
 * A simple [Fragment] subclass.
 * Use the [AsiaFrag.newInstance] factory method to
 * create an instance of this fragment.
 */
class AsiaFrag : Fragment() {
    // TODO: Rename and change types of parameters
    private var param1: String? = null
    private var param2: String? = null
    private var  asyncTask:AsyncTask<PrecomputedText.Params,ProgressBar,Result>?=null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val asiaLayout= inflater.inflate(R.layout.fragment_asia, container, false)

        val mAsiaLv:ListView=asiaLayout.findViewById(R.id.asialv_id)

        val msearchvw:androidx.appcompat.widget.SearchView=asiaLayout.findViewById(R.id.asiasearchid)
        msearchvw.queryHint="Search Among Countries"
        msearchvw.isIconified=false





        val dbHelper=AssetOpenHelper(requireActivity())
        val dataBase=dbHelper.readableDatabase
        var myCursor=dataBase.rawQuery("SELECT * FROM ASIA",null)

        val mCursorAdapter=CustomCursorAdapter(requireContext(),myCursor)
        mAsiaLv.adapter=mCursorAdapter



        //on item click listner go to other activity
     mAsiaLv.setOnItemClickListener { parent, view, position, id->


         var mcountryName=myCursor?.getString(1)
         var mcapitalName=myCursor?.getString(2)
         var mcurrencyName=myCursor?.getString(3)
         var mlanguageName=myCursor?.getString(4)
         var mareaName=myCursor?.getString(6)
         var mpopulation=myCursor?.getString(5)
         var mimageName=myCursor?.getString(7)

         val intentToDetails= Intent(requireContext(),CountryDetails::class.java)
            intentToDetails.putExtra("icountryName",mcountryName)
            intentToDetails.putExtra("icapitalName",mcapitalName)
            intentToDetails.putExtra("icurrencyName",mcurrencyName)
            intentToDetails.putExtra("ilanguageName",mlanguageName)
            intentToDetails.putExtra("iareaName",mareaName)
            intentToDetails.putExtra("ipopulation",mpopulation)
            intentToDetails.putExtra("iimageName",mimageName)

            startActivity(intentToDetails)

        }

        // code for search view to search among listview items
        msearchvw.setOnQueryTextListener(object : SearchView.OnQueryTextListener,
            androidx.appcompat.widget.SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(p0: String?): Boolean {
                return false
            }

            override fun onQueryTextChange(p0: String?): Boolean {

                myCursor=dataBase.rawQuery("SELECT * FROM ASIA WHERE COUNTRY LIKE '%${p0}%' OR CAPITAL LIKE '${p0}'",null )
                mCursorAdapter.changeCursor(myCursor)
                return false
            }

        }
        )



        return asiaLayout
    }

    companion object {
        /**
         * Use this factory method to create a new instance of
         * this fragment using the provided parameters.
         *
         * @param param1 Parameter 1.
         * @param param2 Parameter 2.
         * @return A new instance of fragment AsiaFrag.
         */
        // TODO: Rename and change types and number of parameters
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            AsiaFrag().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }




}

//////////////// 这是我的 xml 文件

<

?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".AsiaFrag">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
 android:orientation="vertical">

<androidx.appcompat.widget.SearchView
    android:id="@+id/asiasearchid"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

 <ListView
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:id="@+id/asialv_id"/>
</LinearLayout>
</FrameLayout>

/////////////// sqlite数据库开启助手

package com.example.countriescapitals_continentwise

import android.app.Activity
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.util.Log
import androidx.fragment.app.FragmentActivity
import java.io.File
import java.io.FileOutputStream

/// creating constants
const val dbName = "COUNTRY_DETAILS.db"
const val dbVersionNumber = 1

class AssetOpenHelper(private val context: Context):SQLiteOpenHelper(context,dbName,null, dbVersionNumber) {

    private var dataBase:SQLiteDatabase?=null

    init {
        // Check if the database already copied to the device.
        val dbExist = checkDatabase()
        if (dbExist) {
            // if already copied then don't do anything.
            Log.e("-----", "Database exist")
        } else {
            // else copy the database to the device.
            Log.e("-----", "Database doesn't exist")
            createDatabase()
        }
    }

    private fun createDatabase() {
        copyDatabase()
    }

    private fun checkDatabase(): Boolean {
        val dbFile = File(context.getDatabasePath(dbName).path)
        return dbFile.exists()
    }


    private fun copyDatabase() {

        val inputStream = context.assets.open("databases/$dbName")
        val outputFile = File(context.getDatabasePath(dbName).path)
        val outputStream = FileOutputStream(outputFile)

        val bytesCopied = inputStream.copyTo(outputStream)
        Log.e("bytesCopied", "$bytesCopied")

        inputStream.close()
        outputStream.flush()
        outputStream.close()
    }

    // Open the database with read and write access mode.
    private fun openDatabase() {
        dataBase = SQLiteDatabase.openDatabase(context.getDatabasePath(dbName).path, null, SQLiteDatabase.OPEN_READWRITE)
    }

    // Close the database.
    override fun close() {
        dataBase?.close()
        super.close()
    }



    override fun onCreate(p0: SQLiteDatabase?) {

    }

    override fun onUpgrade(p0: SQLiteDatabase?, p1: Int, p2: Int) {

    }

}

切勿在主线程中进行数据库操作。

始终为数据库操作创建一个单独的函数。 使用加载程序来防止用户多次点击。

    viewModelScope.launch(){
                dbOperations()
            }

    private suspend fun dbOperations() {
       //Do your db task here. its background thread
            withContext(Dispatchers. Main) {

              //call next activity here. it is main thread.
    
            }
        }