香雨站

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 120|回复: 1

Android连接远程MySQL的各种问题

[复制链接]

3

主题

5

帖子

10

积分

新手上路

Rank: 1

积分
10
发表于 2022-9-21 17:54:35 | 显示全部楼层 |阅读模式
Android连接远程数据库的避坑指南

今天用Android Studio连接数据库时候,写了个测试连接的按钮,然后连接的时候报错了,报错信息:
2021-09-07 22:45:20.433 7054-7083/cn.xuziao.faceprocess E/AndroidRuntime: FATAL EXCEPTION: Thread-113
    Process: cn.xuziao.faceprocess, PID: 7054
    java.lang.NoSuchMethodError: No virtual method group(Ljava/lang/String;)Ljava/lang/String; in class Ljava/util/regex/Matcher; or its super classes (declaration of 'java.util.regex.Matcher' appears in /system/framework/core-libart.jar)
        at com.mysql.cj.conf.ConnectionUrlParser.isConnectionStringSupported(ConnectionUrlParser.java:152)
        at com.mysql.cj.conf.ConnectionUrl.acceptsUrl(ConnectionUrl.java:317)
        at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:186)
        at java.sql.DriverManager.getConnection(DriverManager.java:179)
        at java.sql.DriverManager.getConnection(DriverManager.java:213)
        at cn.xuziao.faceprocess.LoginActivity$1$1.run(LoginActivity.java:38)
        at java.lang.Thread.run(Thread.java:818)
然后我当时写的按钮点击执行方法片段
textView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://172.17.9.241:3306/user_info";
            String login_username = "login";
            String login_password = "root";
            Connection connection = DriverManager.getConnection(url, login_username, login_password);
            String sql = "select username from base_info";
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(sql);
            while (resultSet.next()){
                Log.d(TAG, resultSet.getString(1));
            }
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
        Toast.makeText(LoginActivity.this, "注册中...", Toast.LENGTH_SHORT).show();
    }
});
附上当时的build.gradle文件里面我导入的依赖
dependencies {

    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    implementation 'mysql:mysql-connector-java:8.0.26'
}
最后一行是我引入的依赖
然后我就查到,安卓的主线程不能访问网络,具体博客:https://www.cnblogs.com/lyroge/p/3837902.html
引入后的代码:
textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Class.forName("com.mysql.jdbc.Driver");
                            String url = "jdbc:mysql://172.17.9.241:3306/user_info";
                            String login_username = "login";
                            String login_password = "root";
                            Connection connection = DriverManager.getConnection(url, login_username, login_password);
                            String sql = "select username from base_info";
                            Statement statement = connection.createStatement();
                            ResultSet resultSet = statement.executeQuery(sql);
                            while (resultSet.next()){
                                Log.d(TAG, resultSet.getString(1));
                            }
                        } catch (ClassNotFoundException | SQLException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
                Toast.makeText(LoginActivity.this, "注册中...", Toast.LENGTH_SHORT).show();
            }
        });
然后我引入了多线程,还是报错,报错信息跟上面是一样的,那就说明问题不只主线程不能访问网络的问题,然后我就改了好久奇奇怪怪的东西,我就看到我的安卓自带的jdk版本是1.8但是我的MySQL驱动到了8,然后我就去把MySQL驱动换成了5,build.gradle依赖部分改为:
dependencies {

    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    implementation 'mysql:mysql-connector-java:5.1.6'

}
然后我发现上面那个报错的问题解决了,然后报了新的错:
W/System.err: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
    Last packet sent to the server was 0 ms ago.
        at java.lang.reflect.Constructor.newInstance(Native Method)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
        at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074)
        at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2103)
        at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:718)
        at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46)
        at java.lang.reflect.Constructor.newInstance(Native Method)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
        at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:302)
        at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:282)
        at java.sql.DriverManager.getConnection(DriverManager.java:179)
        at java.sql.DriverManager.getConnection(DriverManager.java:213)
        at cn.xuziao.faceprocess.LoginActivity$1$1.run(LoginActivity.java:37)
        at java.lang.Thread.run(Thread.java:818)
    Caused by: java.net.UnknownHostException: Unable to resolve host "172.17.9.241": No address associated with hostname
        at java.net.InetAddress.lookupHostByName(InetAddress.java:470)
        at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
        at java.net.InetAddress.getAllByName(InetAddress.java:215)
        at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:243)
        at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:280)
        at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2026)
        ... 10 more
W/System.err: Caused by: android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
        at libcore.io.Posix.android_getaddrinfo(Native Method)
        at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:55)
        at java.net.InetAddress.lookupHostByName(InetAddress.java:451)
        ... 15 more
    Caused by: android.system.ErrnoException: android_getaddrinfo failed: ECONNREFUSED (Connection refused)
        ... 18 more
这个错是被异常捕获机制捕获到的一个错误,说明MySQL驱动是成功导入而且能够使用了,然后通过查资料了解到,要解决这个错误只需要在AndroidManifest.xml文件里面加一行<uses-permission android:name="android.permission.INTERNET"/>就行了
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.xuziao.faceprocess">
    <!--要加在application标签的上面-->
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="false"
        android:icon="@mipmap/real_launcher_logo"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.FaceProcess"
        >
        <activity
            android:name=".LoginActivity"
            android:exported="true"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".MainActivity"
            android:exported="true"/>
    </application>
</manifest>
然后问题成功解决
总结

1. 安卓连接网络要使用多线程,不能直接用主线程

2. MySQL驱动版本不宜过高,我这边试的5是可以的,8不行,至于6、7暂时还不清楚

之后我又新建了一个Java工程,用的jdk8但是使用MySQL8的驱动是可以正确连接的,不知道Android为什么不行,如果有知道的希望能在评论区一起分享一下
3. 要记得在AndroidManifest.xml文件里面加上<uses-permission android:name="android.permission.INTERNET"/>这一行
回复

使用道具 举报

1

主题

2

帖子

3

积分

新手上路

Rank: 1

积分
3
发表于 2022-9-21 17:55:20 | 显示全部楼层
我也是MySQL可以远程链接,但是Android studio连不上[大哭]愁死了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|香雨站

GMT+8, 2025-3-15 04:53 , Processed in 0.285370 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.. 技术支持 by 巅峰设计

快速回复 返回顶部 返回列表