Android URL Connection error: Database connection error using XAMPP
Android URL Connection error: Database connection error using XAMPP
我目前正在构建一个需要管理历史交易数据库的项目。
我按照本网站的说明将我的数据库连接到项目:
How To Connect An Android App To A MySQL Database
之后,我尝试使用 Fragment_History
中的这段代码构建我的项目,但是,出现了这个错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mind.loginregisterapps, PID: 6912
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:121)
at org.json.JSONTokener.nextValue(JSONTokener.java:98)
at org.json.JSONArray.<init>(JSONArray.java:94)
at org.json.JSONArray.<init>(JSONArray.java:110)
at com.mind.loginregisterapps.Fragment_History.loadIntoListView(Fragment_History.java:83)
at com.mind.loginregisterapps.Fragment_History.access[=10=]0(Fragment_History.java:24)
at com.mind.loginregisterapps.Fragment_HistoryDownloadJSON.onPostExecute(Fragment_History.java:55)
at com.mind.loginregisterapps.Fragment_HistoryDownloadJSON.onPostExecute(Fragment_History.java:42)
at android.os.AsyncTask.finish(AsyncTask.java:771)
at android.os.AsyncTask.access0(AsyncTask.java:199)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:788)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
我检查了代码,发现由于 downloadJSON.
中连接失败 URL 传递了空值
因此,我添加了res/xml/network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">localhost</domain>
</domain-config>
</network-security-config>
并编辑清单:
<application
...
android:networkSecurityConfig="@xml/network_security_config"
android:usesCleartextTraffic="true"
</application>
但是,使用HTTPUrlConnection
时出现了这个错误,我迷迷糊糊了:
Failed to connect to localhost/127.0.0.1:80
我试图在 downloadJSON
和 network_security_config.xml
中将 localhost 更改为 127.0.0.1,错误变成:
Failed to connect to /127.0.0.1:80
我该如何解决这个问题?请告诉我。
非常感谢!
这是代码:
Fragment_History.java
public class Fragment_History extends Fragment {
ListView listView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_history, container, false);
listView = (ListView)view.findViewById(R.id.list_history);
downloadJSON("http://localhost/hist_login.php");
return view;
}
private void downloadJSON(final String urlWebService) {
class DownloadJSON extends AsyncTask<Void, Void, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Toast.makeText(getActivity(), s, Toast.LENGTH_SHORT).show();
try {
loadIntoListView(s);
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
protected String doInBackground(Void... voids) {
try {
URL url = new URL(urlWebService);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
StringBuilder sb = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String json;
while ((json = bufferedReader.readLine()) != null) {
sb.append(json + "\n");
}
return sb.toString().trim();
} catch (Exception e) {
return null;
}
}
}
DownloadJSON getJSON = new DownloadJSON();
getJSON.execute();
}
private void loadIntoListView(String json) throws JSONException {
JSONArray jsonArray = new JSONArray(json);
ArrayList<History> list = new ArrayList<History>();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
list.add(new History(obj.getString("h_rName"),obj.getDouble("h_amount")));
}
HistoryAdapter adapter = new HistoryAdapter(list, getActivity());
listView.setAdapter(adapter);
}
}
hist_login.php:
<?php
$db = "test";
$user = "root";
$pass = "";
$host = "localhost";
// Create connection
$con=mysqli_connect($host,$user,$pass,$db);
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
// Select all of our stocks from table 'history'
$sql = "SELECT * FROM history";
// Confirm there are results
if ($result = mysqli_query($con, $sql))
{
// We have results, create an array to hold the results
// and an array to hold the data
$resultArray = array();
$tempArray = array();
// Loop through each result
while($row = $result->fetch_object())
{
// Add each result into the results array
$tempArray = $row;
array_push($resultArray, $tempArray);
}
// Encode the array to JSON and output the results
echo json_encode($resultArray);
} else
{
echo "Not connected...";
}
// Close connections
mysqli_close($con);
?>
我自己设法解决了。我所做的是将 http 更改为:
http://10.0.2.2/hist_login.php
因为它是 Android Studi 上模拟器的域。
是的,如果您使用的是模拟器。在 Android Studio emulator-host network Host`s ip is 10.0.2.2
有时我在模拟器上,有时有一个真实的设备,我在更改它时遇到了这个问题。所以我做了这个配置,你可以使用
在模块 build.gradle
android{
buildTypes {
release {
debuggable false
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildConfigField "String" , "BASE_URL" , "\"https://acme.co/\""
resValue "string", "BASE_URL_SCHEME", "\"https\""
resValue "string", "BASE_URL_HOST", "\"acme.co\""
manifestPlaceholders = [crashlyticsEnabled: true]
}
debug {
debuggable true
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
ext.alwaysUpdateBuildId = false
//debug with server url
buildConfigField 'String' , 'BASE_URL' , "\"https://acme.co/\""
resValue "string", "BASE_URL_SCHEME", "\"https\""
resValue "string", "BASE_URL_HOST", "\"acme.co\""
ext.enableCrashlytics = false
manifestPlaceholders = [crashlyticsEnabled: false]
}
debug_emulator{
debuggable true
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
ext.alwaysUpdateBuildId = false
//"http://10.0.2.2/tak/public/"
buildConfigField 'String' , 'BASE_URL' , "\"http://10.0.2.2/\""
resValue "string", "BASE_URL_SCHEME", "\"http\""
resValue "string", "BASE_URL_HOST", "\"10.0.2.2\""
ext.enableCrashlytics = false
manifestPlaceholders = [crashlyticsEnabled: false]
}
debug_physical{
debuggable true
minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
ext.alwaysUpdateBuildId = false
//"http://192.168.43.100/tak/public/"
buildConfigField 'String' , 'BASE_URL' , "\"http://192.168.43.100/\""
resValue "string", "BASE_URL_SCHEME", "\"http\""
resValue "string", "BASE_URL_HOST", "\"192.168.43.100\""
ext.enableCrashlytics = false
manifestPlaceholders = [crashlyticsEnabled: false]
}
}
}
所以我这里有 4 个 url 配置如下:
- 发布 应用程序发布
- debug 用于调试和使用服务器 ip/domain 示例:acme.co
- debug_emulator 在我使用 Android Studio 模拟器和服务器时进行调试 (你的情况)
- debug_physical 当我在与本地服务器位于同一专用网络中的真实设备上进行调试时。
我在 Android 中使用 url 代码如下:
public static final String BASE_URL = BuildConfig.BASE_URL;
当我想编译时,我唯一要做的就是这个 buildType。这些设置将插入正确的 url。
只需在从下拉菜单编译之前更改它:
我目前正在构建一个需要管理历史交易数据库的项目。
我按照本网站的说明将我的数据库连接到项目:
How To Connect An Android App To A MySQL Database
之后,我尝试使用 Fragment_History
中的这段代码构建我的项目,但是,出现了这个错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mind.loginregisterapps, PID: 6912
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:121)
at org.json.JSONTokener.nextValue(JSONTokener.java:98)
at org.json.JSONArray.<init>(JSONArray.java:94)
at org.json.JSONArray.<init>(JSONArray.java:110)
at com.mind.loginregisterapps.Fragment_History.loadIntoListView(Fragment_History.java:83)
at com.mind.loginregisterapps.Fragment_History.access[=10=]0(Fragment_History.java:24)
at com.mind.loginregisterapps.Fragment_HistoryDownloadJSON.onPostExecute(Fragment_History.java:55)
at com.mind.loginregisterapps.Fragment_HistoryDownloadJSON.onPostExecute(Fragment_History.java:42)
at android.os.AsyncTask.finish(AsyncTask.java:771)
at android.os.AsyncTask.access0(AsyncTask.java:199)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:788)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
我检查了代码,发现由于 downloadJSON.
中连接失败 URL 传递了空值因此,我添加了res/xml/network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">localhost</domain>
</domain-config>
</network-security-config>
并编辑清单:
<application
...
android:networkSecurityConfig="@xml/network_security_config"
android:usesCleartextTraffic="true"
</application>
但是,使用HTTPUrlConnection
时出现了这个错误,我迷迷糊糊了:
Failed to connect to localhost/127.0.0.1:80
我试图在 downloadJSON
和 network_security_config.xml
中将 localhost 更改为 127.0.0.1,错误变成:
Failed to connect to /127.0.0.1:80
我该如何解决这个问题?请告诉我。
非常感谢!
这是代码:
Fragment_History.java
public class Fragment_History extends Fragment {
ListView listView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_history, container, false);
listView = (ListView)view.findViewById(R.id.list_history);
downloadJSON("http://localhost/hist_login.php");
return view;
}
private void downloadJSON(final String urlWebService) {
class DownloadJSON extends AsyncTask<Void, Void, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Toast.makeText(getActivity(), s, Toast.LENGTH_SHORT).show();
try {
loadIntoListView(s);
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
protected String doInBackground(Void... voids) {
try {
URL url = new URL(urlWebService);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
StringBuilder sb = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String json;
while ((json = bufferedReader.readLine()) != null) {
sb.append(json + "\n");
}
return sb.toString().trim();
} catch (Exception e) {
return null;
}
}
}
DownloadJSON getJSON = new DownloadJSON();
getJSON.execute();
}
private void loadIntoListView(String json) throws JSONException {
JSONArray jsonArray = new JSONArray(json);
ArrayList<History> list = new ArrayList<History>();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
list.add(new History(obj.getString("h_rName"),obj.getDouble("h_amount")));
}
HistoryAdapter adapter = new HistoryAdapter(list, getActivity());
listView.setAdapter(adapter);
}
}
hist_login.php:
<?php
$db = "test";
$user = "root";
$pass = "";
$host = "localhost";
// Create connection
$con=mysqli_connect($host,$user,$pass,$db);
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
// Select all of our stocks from table 'history'
$sql = "SELECT * FROM history";
// Confirm there are results
if ($result = mysqli_query($con, $sql))
{
// We have results, create an array to hold the results
// and an array to hold the data
$resultArray = array();
$tempArray = array();
// Loop through each result
while($row = $result->fetch_object())
{
// Add each result into the results array
$tempArray = $row;
array_push($resultArray, $tempArray);
}
// Encode the array to JSON and output the results
echo json_encode($resultArray);
} else
{
echo "Not connected...";
}
// Close connections
mysqli_close($con);
?>
我自己设法解决了。我所做的是将 http 更改为:
http://10.0.2.2/hist_login.php
因为它是 Android Studi 上模拟器的域。
是的,如果您使用的是模拟器。在 Android Studio emulator-host network Host`s ip is 10.0.2.2
有时我在模拟器上,有时有一个真实的设备,我在更改它时遇到了这个问题。所以我做了这个配置,你可以使用
在模块 build.gradle
android{
buildTypes {
release {
debuggable false
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildConfigField "String" , "BASE_URL" , "\"https://acme.co/\""
resValue "string", "BASE_URL_SCHEME", "\"https\""
resValue "string", "BASE_URL_HOST", "\"acme.co\""
manifestPlaceholders = [crashlyticsEnabled: true]
}
debug {
debuggable true
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
ext.alwaysUpdateBuildId = false
//debug with server url
buildConfigField 'String' , 'BASE_URL' , "\"https://acme.co/\""
resValue "string", "BASE_URL_SCHEME", "\"https\""
resValue "string", "BASE_URL_HOST", "\"acme.co\""
ext.enableCrashlytics = false
manifestPlaceholders = [crashlyticsEnabled: false]
}
debug_emulator{
debuggable true
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
ext.alwaysUpdateBuildId = false
//"http://10.0.2.2/tak/public/"
buildConfigField 'String' , 'BASE_URL' , "\"http://10.0.2.2/\""
resValue "string", "BASE_URL_SCHEME", "\"http\""
resValue "string", "BASE_URL_HOST", "\"10.0.2.2\""
ext.enableCrashlytics = false
manifestPlaceholders = [crashlyticsEnabled: false]
}
debug_physical{
debuggable true
minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
ext.alwaysUpdateBuildId = false
//"http://192.168.43.100/tak/public/"
buildConfigField 'String' , 'BASE_URL' , "\"http://192.168.43.100/\""
resValue "string", "BASE_URL_SCHEME", "\"http\""
resValue "string", "BASE_URL_HOST", "\"192.168.43.100\""
ext.enableCrashlytics = false
manifestPlaceholders = [crashlyticsEnabled: false]
}
}
}
所以我这里有 4 个 url 配置如下:
- 发布 应用程序发布
- debug 用于调试和使用服务器 ip/domain 示例:acme.co
- debug_emulator 在我使用 Android Studio 模拟器和服务器时进行调试 (你的情况)
- debug_physical 当我在与本地服务器位于同一专用网络中的真实设备上进行调试时。
我在 Android 中使用 url 代码如下:
public static final String BASE_URL = BuildConfig.BASE_URL;
当我想编译时,我唯一要做的就是这个 buildType。这些设置将插入正确的 url。
只需在从下拉菜单编译之前更改它: