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

Android Studio连接MySQL失败,添加网络权限后应用崩溃求助

问题分析与解决方案

核心崩溃原因

你的代码存在几个关键问题,导致应用崩溃:

  • 主线程执行网络IO:即使通过StrictMode临时放宽限制,Android高版本(尤其是API 28+)对主线程网络操作的管控依然严格,这不仅会引发崩溃,还会导致ANR(应用无响应)。
  • 可能缺失MySQL JDBC驱动依赖:Android SDK默认不包含MySQL的JDBC驱动,若未在项目中引入依赖,会触发ClassNotFoundException导致崩溃。
  • 未正确关闭数据库资源:Connection、Statement、ResultSet使用后未关闭,会造成资源泄漏,长期运行引发异常。
  • SQL注入风险:直接拼接字符串构建SQL语句,存在严重安全隐患,同时可能因特殊字符导致SQL语法错误。

分步修复方案

1. 引入MySQL JDBC驱动依赖

在项目的build.gradle(Module level)的dependencies块中添加驱动依赖:

dependencies {
    // 其他依赖...
    implementation 'mysql:mysql-connector-java:8.0.33'
}

注意:如果是Android Studio Arctic Fox及以上版本,需在settings.gradle中确保添加mavenCentral仓库:

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral() // 必须添加此行
    }
}

2. 移除非主线程执行网络操作

使用后台线程执行数据库操作,避免阻塞主线程。推荐使用Coroutine(现代Android开发方式)或AsyncTask(兼容旧版本):

方案一:使用Coroutine(推荐)

先确保项目引入Coroutine依赖:

dependencies {
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
}

修改MainActivity代码:

package com.database.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.PreparedStatement;
import kotlinx.coroutines.CoroutineScope;
import kotlinx.coroutines.Dispatchers;
import kotlinx.coroutines.MainScope;
import kotlinx.coroutines.launch;

public class MainActivity extends AppCompatActivity implements CoroutineScope by MainScope() {
    private TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = findViewById(R.id.denemetext);
        
        // IO线程执行数据库操作,主线程更新UI
        launch(Dispatchers.IO) {
            String result = testDB("onur");
            launch(Dispatchers.Main) {
                tv.setText(result);
            }
        }
    }

    private String testDB(String name) {
        Connection con = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
            // MySQL 8.0+驱动类名已变更
            Class.forName("com.mysql.cj.jdbc.Driver"); 
            con = DriverManager.getConnection(
                    "jdbc:mysql://192.168.56.1:3306/giris_sistemi?useSSL=false&serverTimezone=UTC",
                    "onur", "12345");
            String result = "Database connection success\n";
            
            // 使用PreparedStatement防止SQL注入
            String sql = "select * from kisiler where kisi_name like ?";
            st = con.prepareStatement(sql);
            st.setString(1, "%" + name + "%"); // 模糊查询需添加%
            rs = st.executeQuery();
            
            ResultSetMetaData rsmd = rs.getMetaData();
            while(rs.next()) {
                result += rsmd.getColumnName(1) + ": " + rs.getString(1) + "\n";
                result += rsmd.getColumnName(2) + ": " + rs.getInt(2) + "\n";
                result += rsmd.getColumnName(3) + ": " + rs.getString(3) + "\n";
            }
            return result;
        } catch(Exception e) {
            e.printStackTrace();
            return e.toString();
        } finally {
            // 关闭资源,避免泄漏
            try {
                if(rs != null) rs.close();
                if(st != null) st.close();
                if(con != null) con.close();
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    }
}

方案二:使用AsyncTask(兼容旧版本)

package com.database.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.TextView;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.PreparedStatement;

public class MainActivity extends AppCompatActivity {
    private TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = findViewById(R.id.denemetext);
        new DBTask().execute("onur");
    }

    private class DBTask extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... params) {
            Connection con = null;
            PreparedStatement st = null;
            ResultSet rs = null;
            try {
                Class.forName("com.mysql.cj.jdbc.Driver");
                con = DriverManager.getConnection(
                        "jdbc:mysql://192.168.56.1:3306/giris_sistemi?useSSL=false&serverTimezone=UTC",
                        "onur", "12345");
                String result = "Database connection success\n";
                String sql = "select * from kisiler where kisi_name like ?";
                st = con.prepareStatement(sql);
                st.setString(1, "%" + params[0] + "%");
                rs = st.executeQuery();
                ResultSetMetaData rsmd = rs.getMetaData();
                while(rs.next()) {
                    result += rsmd.getColumnName(1) + ": " + rs.getString(1) + "\n";
                    result += rsmd.getColumnName(2) + ": " + rs.getInt(2) + "\n";
                    result += rsmd.getColumnName(3) + ": " + rs.getString(3) + "\n";
                }
                return result;
            } catch(Exception e) {
                e.printStackTrace();
                return e.toString();
            } finally {
                try {
                    if(rs != null) rs.close();
                    if(st != null) st.close();
                    if(con != null) con.close();
                } catch(Exception e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        protected void onPostExecute(String result) {
            tv.setText(result);
        }
    }
}

3. 精简Manifest配置

移除不必要的权限(你的代码无需定位、电话等权限),精简后的AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <!-- 仅保留必要的网络权限 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApplication"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

4. 额外注意事项

  • MySQL版本兼容:MySQL 8.0+需使用com.mysql.cj.jdbc.Driver驱动类,且URL需添加serverTimezone参数(如serverTimezone=UTC)。
  • 网络可达性:确保测试设备与MySQL服务器在同一局域网,且服务器允许外部连接(修改MySQL配置的bind-address为0.0.0.0,并授权远程访问权限)。
  • 生产环境建议:Android应用直接用JDBC连接MySQL并非最佳实践,推荐通过后端API(如Spring Boot、Node.js)中转数据库操作,提升安全性与性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 10:35:18