我有以下问题。 我想创建一个无需绕过弯路即可直接访问SQL Server数据库的应用程序。
但是,我发现错误不是应用程序崩溃的原因。并不是真正可以帮助我摆脱困境的东西。我很感谢你的帮助 每当我按下连接按钮时,我的应用就会在模拟器中崩溃。
MainActivity.java
package com.example.sql_query;
imports;
public class MainActivity extends Activity {
Button btnConnect, btnAdd, btnDel, btnCom;
TextView tv;
EditText etINSERT;
Connection conn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tvDs);
etLieferkennung = (EditText) findViewById(R.id.etLieferkennung);
btnAdd = (Button) findViewById(R.id.btnAdd);
btnAdd.setEnabled(false);
btnConnect = (Button) findViewById(R.id.btnConnect);
btnConnect.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Query();
btnConnect.setEnabled(false);
btnAdd.setEnabled(true);
}
});
btnAdd = (Button) findViewById(R.id.btnAdd);
btnAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
connect();
PreparedStatement comm;
try {
comm = conn.prepareStatement("insert into DATABASE("
+ "COLOUMN) values(?)");
comm.setString(1, etINSERT.getText().toString());
comm.executeUpdate();
} catch (SQLException e) {
tv.setText(e.toString());
}
Query();
}
});
}
public void connect() {
try {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
Class.forName("net.sourceforge.jtds.jdbc.Driver");
conn = DriverManager.getConnection(""
+ "jdbc:jtds:sqlserver://IP/DATABASENAME;"
+ "user=EXAMPLE;password=EXAMPLE;");
} catch (Exception e) {
tv.setText(e.toString());
}
}
public void Query() {
connect();
Statement comm;
try {
comm = conn.createStatement();
ResultSet rs = comm.executeQuery("SELECT COLOUMNS FROM DATABASE Order by ID");
String msg = "";
while (rs.next()) {
msg += "\nID: " + rs.getInt("ID") + " Lieferkennung: "
+ rs.getString("Lieferkennung") + " Datum: "
+ rs.getString("Datum");
}
tv.setText(msg);
} catch (SQLException e) {
tv.setText(e.toString());
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp"
android:background="@color/costum"
android:orientation="vertical"
tools:context="${relativePackage}.${activityClass}" >
<EditText
android:id="@+id/etINSERT"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:background="#eeeeee"
android:hint="INSERT"
android:padding="4dp"
android:textColor="#000000"
android:textSize="24dp">
<requestFocus />
</EditText>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="4dp">
<Button
android:id="@+id/btnConnect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:backgroundTint="@color/costum"
android:text="Connect" />
<Button
android:id="@+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:backgroundTint="@color/costum"
android:text="Add new" />
<Button
android:id="@+id/btnDel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:backgroundTint="@color/Tumeric"
android:text="Delete Old" />
<Button
android:id="@+id/btnCom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/Tumeric"
android:text="Compare" />
</LinearLayout>
<TextView
android:id="@+id/tvDs"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:padding="8dp"
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
这是错误消息
EAndroidRuntime FATAL EXCEPTION main
Process com.example.sql_query, PID 19201
java.lang.NullPointerException Attempt to invoke interface method 'java.sql.Statement java.sql.Connection.createStatement()' on a null object reference
at com.example.sql_query.MainActivity.Query(MainActivity.java86)
at com.example.sql_query.MainActivity$1.onClick(MainActivity.java40)
at android.view.View.performClick(View.java6256)
at android.view.View$PerformClick.run(View.java24701)
at android.os.Handler.handleCallback(Handler.java789)
at android.os.Handler.dispatchMessage(Handler.java98)
at android.os.Looper.loop(Looper.java164)
at android.app.ActivityThread.main(ActivityThread.java6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java767)
希望你能帮助我。
答案 0 :(得分:0)
如果在connect()
函数中Query()
调用失败,则conn
未初始化。因此,调用conn.createStatement()
会引发NullPointerException。
通常,仅通过记录/显示错误消息并继续来处理异常是一个非常糟糕的主意。您应该停止常规控制流,以使对象处于有效状态。例如,如果连接失败,则可以停止Query()
方法。点击处理程序也是如此。
您可以通过在connect
中引发异常并在调用该函数的地方对其进行处理来处理错误:
public void connect() throws Exception {
// ...
conn = DriverManager.getConnection(/* ... */);
}
public void Query() {
try {
connect();
} catch (Exception e) {
// handle the error (i.e. show error message)
return;
}
// ...
try {
comm = conn.createStatement();
// ...
} catch (SQLException e) {
tv.setText(e.toString());
}
}
或者,您可以检查连接呼叫是否按预期工作:
public void Query() {
connect();
if (conn == null) {
// connection could not be initialized, the error message is
// set in connect()
return;
}
Statement comm;
try {
comm = conn.createStatement();
// ...
} catch (SQLException e) {
tv.setText(e.toString());
}
}