使用 JDBC 驱动程序执行 Sql 查询时出现 NetworkOnMainThreadException

Posted

技术标签:

【中文标题】使用 JDBC 驱动程序执行 Sql 查询时出现 NetworkOnMainThreadException【英文标题】:NetworkOnMainThreadException while executing Sql query using JDBC driver 【发布时间】:2019-09-12 09:49:29 【问题描述】:

我正在使用 JDBC 驱动程序执行 sql 查询,但它给了我 NetworkOnMainThreadException。我已使用 Asyntask 进行网络操作,并在清单文件中提及 Internet 权限。下面是我执行查询的代码

public class getLedger extends AsyncTask<String, Void, Void> 

    private ProgressDialog progressDlg;
    private ResultSet rs;

    @Override
    protected void onPreExecute() 
        super.onPreExecute();
        progressDlg = new ProgressDialog(LedgerActivity.this);
        progressDlg.setMessage("Please wait...");
        progressDlg.setIndeterminate(false);
        progressDlg.setProgressStyle(android.R.style.Widget_ProgressBar_Small);
        progressDlg.setCancelable(false);
        progressDlg.show();
    

    @Override
    protected Void doInBackground(String... strings) 
        SharedPreferences pref = getSharedPreferences("Login", Context.MODE_PRIVATE);
        String ip = pref.getString("ip", "");
        String username = pref.getString("username", "");
        String password = pref.getString("password", "");
        String dbname = pref.getString("dbname", "");
        rs = new ExecuteQuery().selectdata(ip, username, password, strings[0], dbname);
        return null;
    

    @Override
    protected void onPostExecute(Void aVoid) 
        super.onPostExecute(aVoid);
        try 
            if (rs != null) 
                ArrayList<Ledger> ledgerlist = new ArrayList<>();
                while (rs.next()) 
                    String accode = rs.getString("AC_CODE");
                    String acname = rs.getString("AC_NAME");
                    String acaddr = rs.getString("AC_ADD1");
                    String acmobile = rs.getString("AC_MOBILE");
                    String actype = rs.getString("AC_TYPE");
                    String amount = rs.getString("Amount");
                    String goldwt = rs.getString("GoldWt");
                    String silverwt = rs.getString("SilverWt");
                    ledgerlist.add(new Ledger(accode, acname, acaddr, acmobile, actype, amount, goldwt, silverwt));
                
                LedgerAdapter adapter = new LedgerAdapter(LedgerActivity.this, ledgerlist);
                rcv_ledger.setAdapter(adapter);
            
         catch (SQLException e) 
            e.printStackTrace();
         catch (Exception e) 
            e.printStackTrace();
        
    

【问题讨论】:

您不应在 Android 应用程序中使用 JDBC 驱动程序。让您的 Android 应用程序与 REST 服务通信,并让 REST 服务与您的数据库通信。 基本上我正在开发库存管理系统的应用程序,因此它不需要任何休息服务。它完全是 wifi 基础应用程序 【参考方案1】:

看起来对 ResultSet.next() 的调用在后台使用 InputStream 来加载行值或类似的东西。

所以为了避免异常你需要从doInBackground()返回ArrayList&lt;Ledger&gt;而不是在onPostExecute()中解析ResultSet

【讨论】:

根据哪个JDBC文档? docs.oracle.com/javase/7/docs/api/java/sql/… 这些文档中没有任何内容表明它在后台使用InputStream(尽管许多实现都以某种形式使用)。 “如果当前行的输入流打开,则调用 next 方法将隐式关闭它。” 指的是使用getBinaryStream 或其他ResultSet 方法获得的输入流。所以你的结论是正确的,但你得出这个结论的来源却不是。

以上是关于使用 JDBC 驱动程序执行 Sql 查询时出现 NetworkOnMainThreadException的主要内容,如果未能解决你的问题,请参考以下文章

通过 JTDS 驱动程序执行 SQL Server 调用时出现“第 24 行位置的 JDBC 转义语法无效 '=' 预期字符”错误的原因?

执行 SQL 查询时出现 Wix 错误 -2147217900

在 PHP 中执行大型 SQL 查询字符串时出现“内存不足”错误

将 spark 应用程序连接到远程 sql 服务器时出现 jdbc 连接超时错误

在apache spark上执行sql查询时出现arrayindexoutofbound异常

使用JDBC连接将记录插入Apache Ignite Cluster时出现异常