You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

导入数据至数据库时如何实现进度条功能?

Adding a Progress Bar to Your Android Data Import Process

Got it, let's get that progress bar working for your file import. Since you already have the total line count, we can use that to calculate real-time progress and keep your users informed. Here's a step-by-step adjustment to your code:

1. Update Your Dialog Layout

First, add a horizontal progress bar and a progress text view to your import__dialog.xml to display progress:

<!-- Add these to your existing layout -->
<ProgressBar
    android:id="@+id/progress_bar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    style="@style/Widget.AppCompat.ProgressBar.Horizontal"
    android:max="100"
    android:visibility="gone"/>
<TextView
    android:id="@+id/tv_progress"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="0%"
    android:layout_marginTop="8dp"
    android:visibility="gone"/>

2. Adjust Your Kotlin Code for Async Import & Progress Updates

We'll use Kotlin Coroutines to handle heavy file/database work off the main thread, while updating the UI safely on the main thread. Here's the revised code with progress tracking:

// Add these properties at the top of your Activity/Fragment
private lateinit var progressBar: ProgressBar
private lateinit var progressText: TextView
private var totalLines = 0

private fun importDialog(type: Int, context: Context) {
    val builder = AlertDialog.Builder(this)
    val inflater = this.layoutInflater
    val view = inflater.inflate(R.layout.import__dialog, null)
    builder.setView(view)
    val dialog: AlertDialog = builder.create()
    dialog.window?.attributes?.windowAnimations = type
    dialog.setMessage(context.getString(R.string.open_master))
    
    lbl = view.findViewById(R.id.edit_master)
    lbl.text = noti.toString()
    
    // Initialize progress components
    progressBar = view.findViewById(R.id.progress_bar)
    progressText = view.findViewById(R.id.tv_progress)
    
    btnimport = view.findViewById(R.id.img_import)
    btnimport.setOnClickListener {
        val fileintent = Intent(Intent.ACTION_GET_CONTENT)
        fileintent.type = "text/*" // Fixed MIME type for txt/csv
        try {
            startActivityForResult(fileintent, requestcode)
            dialog.show()
        } catch (e: ActivityNotFoundException) {
            lbl.text = "No activity can handle picking a file. Showing alternatives."
        }
    }
    
    scan = view.findViewById<Button>(R.id.btn_scan)
    scan.setOnClickListener {
        // First calculate total lines before starting import
        calculateTotalLines()
        // Then start import with progress
        importWithProgress(this)
    }
    
    dialog.show()
}

// Helper function to calculate total lines (extracted from your existing logic)
private fun calculateTotalLines() {
    val cursor = contentResolver.openInputStream(android.net.Uri.parse(master_path)) ?: return
    try {
        val buffer = BufferedReader(InputStreamReader(cursor))
        buffer.readLine() // Skip header line
        totalLines = 0
        while (buffer.readLine() != null) {
            totalLines++
        }
    } catch (e: IOException) {
        e.printStackTrace()
        val d = Dialog(this)
        d.setTitle("Failed to count lines: ${e.message}")
        d.show()
    } finally {
        cursor.close()
    }
}

// Updated import function with progress tracking
private fun importWithProgress(context: Context) {
    // Show progress UI
    progressBar.visibility = View.VISIBLE
    progressText.visibility = View.VISIBLE
    
    // Launch coroutine for background work
    CoroutineScope(Dispatchers.IO).launch {
        val cursor = contentResolver.openInputStream(android.net.Uri.parse(master_path)) ?: return@launch
        val db = openOrCreateDatabase("database.db", Context.MODE_PRIVATE, null)
        val tableName = "Master"
        
        try {
            db.execSQL("delete from $tableName")
            val file = InputStreamReader(cursor)
            val buffer = BufferedReader(file)
            buffer.readLine() // Skip header
            val contentValues = ContentValues()
            
            db.beginTransaction()
            var currentLine = 0
            
            while (true) {
                val line = buffer.readLine() ?: break
                currentLine++
                
                // Your existing line parsing logic (kept as-is)
                val article_array = ArrayList<String>()
                var desc_array = ArrayList<String>()
                var price_array = ArrayList<String>()
                var isbn_array = ArrayList<String>()
                var total_array = ArrayList<String>()
                
                for(i in 0..12){
                    val article = line[i].toString().replace(" ","")
                    article_array.add(article)
                }
                for(i in 13..62){
                    val desc = line[i].toString()
                    desc_array.add(desc)
                }
                for(i in 63..70){
                    val price = line[i].toString().replace(" ","")
                    price_array.add(price)
                }
                for(i in 71..line.length-1){
                    val isbn = line[i].toString().replace(" ","")
                    isbn_array.add(isbn)
                }
                
                val article_list = article_array.toString().replace(", ","").replace("[","").replace("]","").replace("\n","")
                val desc_list = desc_array.toString().replace(", ","").replace("[","").replace("]","").replace("\n","")
                val price_list = price_array.toString().replace(", ","").replace("[","").replace("]","").replace("\n","")
                val isbn_list:String = isbn_array.toString().replace(", ","").replace("[","").replace("]","").replace("\n","")
                
                total_array.add(article_list)
                total_array.add(desc_list)
                total_array.add(price_list)
                total_array.add(isbn_list)
                
                val article=total_array[0].toString()
                val desc=total_array[1].toString()
                val price=total_array[2].toString()
                val isbn=total_array[3].toString()
                
                contentValues.put("article", article)
                contentValues.put("description", desc)
                contentValues.put("price", price)
                contentValues.put("isbn", isbn)
                
                db.insert(tableName, null, contentValues)
                
                // Calculate progress and update UI on main thread
                val progress = (currentLine.toFloat() / totalLines * 100).toInt()
                withContext(Dispatchers.Main) {
                    progressBar.progress = progress
                    progressText.text = "$progress%"
                }
            }
            
            db.setTransactionSuccessful()
            withContext(Dispatchers.Main) {
                // Hide progress and show success message
                progressBar.visibility = View.GONE
                progressText.visibility = View.GONE
                val d = Dialog(context)
                d.setTitle("Import completed successfully!")
                d.show()
            }
        } catch (e: IOException) {
            if (db.inTransaction()) db.endTransaction()
            withContext(Dispatchers.Main) {
                progressBar.visibility = View.GONE
                progressText.visibility = View.GONE
                val d = Dialog(context)
                d.setTitle("Import failed: ${e.message}")
                d.show()
            }
        } catch (ex: Exception) {
            if (db.inTransaction()) db.endTransaction()
            withContext(Dispatchers.Main) {
                progressBar.visibility = View.GONE
                progressText.visibility = View.GONE
                val d = Dialog(context)
                d.setTitle("Import failed: ${ex.message}")
                d.show()
            }
        } finally {
            db.close()
            cursor.close()
        }
    }
}

// Updated onActivityResult with better error handling
@SuppressLint("MissingSuperCall")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (data == null) return
    if (requestCode == requestcode && resultCode == Activity.RESULT_OK) {
        val filepath = data.data ?: return
        master_path = filepath.toString()
        lbl.text = filepath.toString()
    } else {
        val d = Dialog(this)
        d.setTitle("Only CSV/TXT files allowed or operation cancelled")
        d.show()
    }
}

Key Changes Made:

  • Added progress UI components: A horizontal progress bar and text view to display real-time import percentage.
  • Separated line counting: Extracted total line calculation into its own function to run before starting the import.
  • Kotlin Coroutines: Moved file reading and database operations to a background thread (Dispatchers.IO) to avoid blocking the main thread, and used Dispatchers.Main to safely update the UI.
  • Real-time progress updates: Calculated progress percentage after each line is imported and refreshed the UI immediately.
  • Resource cleanup: Added close() calls for cursors and databases to prevent memory leaks.

A quick side note: Your current line parsing uses line[i] to split characters, which might not work well for standard CSV files (which use delimiters like commas). If you're working with proper CSV data, consider using a library like OpenCSV to handle parsing more reliably—but that's a separate improvement!

内容的提问来源于stack exchange,提问作者kinesis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:11:15