Kotlin安卓MySQL应用运行时出现‘找不到合适驱动’错误求助
Hey there! Let's break down why you're hitting this "No suitable driver found" error and walk through the fixes step by step. The core issue is that Android's runtime environment works very differently from standard Java/Kotlin SE, so the setup that works for your Test.kt won't translate directly to the app.
Why This Happens
- Android's Class Loading Quirks: Manual adding of the MySQL JAR doesn't guarantee the driver class gets loaded correctly in Android's sandboxed environment.
- Network on Main Thread: You're running database operations directly on the UI thread, which Android blocks (and will throw a
NetworkOnMainThreadExceptioneven if the driver issue was fixed). - Localhost Misconfiguration:
127.0.0.1in Android emulator points to the emulator itself, not your computer's local MySQL server. - Cleartext Traffic Restrictions: Android 9+ blocks unencrypted network requests by default, which MySQL JDBC uses unless configured otherwise.
Step-by-Step Fixes
1. Add MySQL Driver via Gradle (Not Manual JAR)
First, remove any manually added JARs and let Gradle manage the dependency properly. Open your app/build.gradle file and add this to the dependencies block:
implementation 'mysql:mysql-connector-java:8.0.33' // Add Kotlin Coroutines for safe background thread handling implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
Sync your project with Gradle files to pull in the dependencies.
2. Fix Network Threading with Coroutines
Never run network/database operations on the main thread. Use Kotlin Coroutines (the modern alternative to AsyncTask) to handle background work:
package com.example.dbtest import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_main.* import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) button.setOnClickListener { // Launch background task on IO dispatcher CoroutineScope(Dispatchers.IO).launch { val dataList = DBCon.connection() // Switch back to main thread to update UI withContext(Dispatchers.Main) { textView.text = if (dataList.isNotEmpty()) { dataList.joinToString("\n") { "${it.id} - ${it.firstName} ${it.lastName}" } } else { "Failed to load data or no results" } } } } } }
3. Update DBCon for Android Environment
Fix the driver loading and connection address, plus clean up resources to avoid leaks:
package com.example.dbtest import java.sql.DriverManager import java.sql.ResultSet import java.sql.SQLException object DBCon { @JvmStatic fun connection(): ArrayList<DataModel> { val list = ArrayList<DataModel>() try { // Explicitly load the MySQL 8+ driver (com.mysql.cj.jdbc.Driver) Class.forName("com.mysql.cj.jdbc.Driver") // Use 10.0.2.2 instead of 127.0.0.1 for Android Studio Emulator // (This points to your computer's localhost) val connection = DriverManager.getConnection( "jdbc:mysql://10.0.2.2:3306/testdb?useSSL=false&serverTimezone=UTC", "root", "" ) val statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE) val result = statement.executeQuery("SELECT `id`, `firstName`, `lastName` FROM `testtable`") while (result.next()){ list.add(DataModel(result.getInt("id"), result.getString("firstName"),result.getString("lastName"))) } // Clean up resources result.close() statement.close() connection.close() } catch (e: SQLException) { e.printStackTrace() } catch (e: ClassNotFoundException) { e.printStackTrace() } return list } }
- Note: For Genymotion emulator, use
10.0.3.2instead of10.0.2.2. Also, ensure your MySQL server allows remote connections (grant access toroot@'%') and your computer's firewall opens port 3306.
4. Update AndroidManifest.xml
Ensure you have the required permissions and allow cleartext traffic:
<uses-permission android:name="android.permission.INTERNET" /> <application ... android:usesCleartextTraffic="true"> <!-- Allows unencrypted MySQL connections --> <!-- Your activities go here --> </application>
Why Test.kt Works But the App Doesn't
Your Test.kt runs in a standard Java/Kotlin SE environment, which:
- Uses a different class loader that properly picks up the JDBC driver
- Has no restrictions on running network operations on the main thread
- Resolves
127.0.0.1to your computer's local MySQL server directly
Important Production Note
Never use direct JDBC connections in a production Android app—it exposes your database credentials and is insecure. Instead, build a simple backend API (e.g., with Spring Boot, Node.js) that your app calls to fetch data. This keeps your database safe and follows mobile app best practices.
内容的提问来源于stack exchange,提问作者Mert

