Android 尝试 POST REST API,应用因致命错误而崩溃
Android trying to POST to REST API, app crashing with Fatal Error
经过一番阅读,我已经确定了这个用于向 REST API 发送 POST 请求的基本代码:
package com.theroom.TestProject;
import android.app.Activity;
//import android.content.Context;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.view.View;
import android.widget.*;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Comparator;
public class TestActivity extends Activity {
private EditText username=null;
private EditText password=null;
private Button login;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.country_prefix);
ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.country_codes, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Comparator comparator = new CountryComparator();
adapter.sort(comparator);
spinner.setAdapter(adapter);
TelephonyManager tMgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
// String mPhoneNumber = tMgr.getLine1Number();
String CountryCode = tMgr.getSimCountryIso();
CountryToPhonePrefix CP = new CountryToPhonePrefix();
String PhoneCountryCode = CP.prefixFor(CountryCode.toUpperCase());
Integer pos = adapter.getPosition(PhoneCountryCode);
spinner.setSelection(pos);
TextView PhoneNumberTV = (TextView) findViewById(R.id.login_Text);
// PhoneNumberTV.setText(PhoneCountryCode);
// this.getWindow().setBackgroundDrawable();
}
public void ToastPhoneNumber(View view) throws IOException {
Toast toast = new Toast(getApplicationContext());
TextView PhoneTV = (TextView) findViewById(R.id.login_Text);
TelephonyManager tMgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
String CountryCode = tMgr.getSimCountryIso();
CountryToPhonePrefix CP = new CountryToPhonePrefix();
String PhoneCountryCode = CP.prefixFor(CountryCode.toUpperCase());
HttpClient httpClient = new DefaultHttpClient();
HttpPost PostRequest = new HttpPost("http://10.0.0.10:8000/api/v1/register");
JSONObject data = new JSONObject();
StringEntity se = new StringEntity(data.toString());
PostRequest.setEntity(se);
PostRequest.setHeader("Accept", "application/json");
PostRequest.setHeader("Content-type", "application/json");
HttpResponse response = httpClient.execute(PostRequest);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
String responseString = out.toString();
out.close();
toast.makeText(this, responseString, Toast.LENGTH_SHORT).show();
//..more logic
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
}
}
当我 运行 代码并单击按钮激活 ToastPhoneNumber 方法时(以前是为了这个,现在它应该要求 API 发送验证短信),这就是我进入 logcat:
02-04 23:11:04.492 820-820/com.theroom.TestProject V/Zygote﹕ Switching descriptor 34 to /dev/null
02-04 23:11:04.492 820-820/com.theroom.TestProject V/Zygote﹕ Switching descriptor 9 to /dev/null
02-04 23:11:04.492 820-820/com.theroom.TestProject D/dalvikvm﹕ Late-enabling CheckJNI
02-04 23:11:04.512 820-820/com.theroom.TestProject I/dalvikvm﹕ Enabling JNI app bug workarounds for target SDK version 10...
02-04 23:11:04.552 820-820/com.theroom.TestProject D/ActivityThread﹕ handleBindApplication:com.theroom.TestProject
02-04 23:11:04.552 820-820/com.theroom.TestProject D/ActivityThread﹕ setTargetHeapUtilization:0.75
02-04 23:11:04.552 820-820/com.theroom.TestProject D/ActivityThread﹕ setTargetHeapMinFree:2097152
02-04 23:11:04.802 820-820/com.theroom.TestProject I/Timeline﹕ Timeline: Activity_idle id: android.os.BinderProxy@418911a8 time:412893749
02-04 23:11:14.212 820-820/com.theroom.TestProject D/AndroidRuntime﹕ Shutting down VM
02-04 23:11:14.212 820-820/com.theroom.TestProject W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x415dedb8)
02-04 23:11:14.222 820-820/com.theroom.TestProject E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.theroom.TestProject, PID: 820
java.lang.IllegalStateException: Could not execute method of the activity
at android.view.View.onClick(View.java:3830)
at android.view.View.performClick(View.java:4445)
at android.view.View$PerformClick.run(View.java:18446)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5146)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at android.view.View.onClick(View.java:3825)
at android.view.View.performClick(View.java:4445)
at android.view.View$PerformClick.run(View.java:18446)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5146)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
at libcore.io.IoBridge.connect(IoBridge.java:112)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:460)
at java.net.Socket.connect(Socket.java:833)
at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
at com.theroom.TestProject.TestActivity.ToastPhoneNumber(TestActivity.java:73)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at android.view.View.onClick(View.java:3825)
at android.view.View.performClick(View.java:4445)
at android.view.View$PerformClick.run(View.java:18446)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5146)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
at dalvik.system.NativeStart.main(Native Method)
你能帮我找出问题所在吗?我发现 Java 的异常很难诊断。它不像 PHP 使用起来那么简单和直观,例如 :(
Caused by: android.os.NetworkOnMainThreadException
您正在尝试从主线程进行网络调用,这在 android 中是不允许的。
从方法 ToastPhoneNumber(View view)
创建一个异步任务
MyTask task = new MyTask()
task.execute();
和任务:
public class MyTask extends AsyncTask<String, Void, String> {
MyTask() {}
@Override
protected Boolean doInBackground(String... params) {
try {
// REST CALL
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
@Override
protected void onPostExecute(final Boolean success) {
if (success) {
// handle post execute
}
}
@Override
protected void onCancelled() {
}
}
这应该有用,希望对您有所帮助!
经过一番阅读,我已经确定了这个用于向 REST API 发送 POST 请求的基本代码:
package com.theroom.TestProject;
import android.app.Activity;
//import android.content.Context;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.view.View;
import android.widget.*;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Comparator;
public class TestActivity extends Activity {
private EditText username=null;
private EditText password=null;
private Button login;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.country_prefix);
ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.country_codes, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Comparator comparator = new CountryComparator();
adapter.sort(comparator);
spinner.setAdapter(adapter);
TelephonyManager tMgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
// String mPhoneNumber = tMgr.getLine1Number();
String CountryCode = tMgr.getSimCountryIso();
CountryToPhonePrefix CP = new CountryToPhonePrefix();
String PhoneCountryCode = CP.prefixFor(CountryCode.toUpperCase());
Integer pos = adapter.getPosition(PhoneCountryCode);
spinner.setSelection(pos);
TextView PhoneNumberTV = (TextView) findViewById(R.id.login_Text);
// PhoneNumberTV.setText(PhoneCountryCode);
// this.getWindow().setBackgroundDrawable();
}
public void ToastPhoneNumber(View view) throws IOException {
Toast toast = new Toast(getApplicationContext());
TextView PhoneTV = (TextView) findViewById(R.id.login_Text);
TelephonyManager tMgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
String CountryCode = tMgr.getSimCountryIso();
CountryToPhonePrefix CP = new CountryToPhonePrefix();
String PhoneCountryCode = CP.prefixFor(CountryCode.toUpperCase());
HttpClient httpClient = new DefaultHttpClient();
HttpPost PostRequest = new HttpPost("http://10.0.0.10:8000/api/v1/register");
JSONObject data = new JSONObject();
StringEntity se = new StringEntity(data.toString());
PostRequest.setEntity(se);
PostRequest.setHeader("Accept", "application/json");
PostRequest.setHeader("Content-type", "application/json");
HttpResponse response = httpClient.execute(PostRequest);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
String responseString = out.toString();
out.close();
toast.makeText(this, responseString, Toast.LENGTH_SHORT).show();
//..more logic
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
}
}
当我 运行 代码并单击按钮激活 ToastPhoneNumber 方法时(以前是为了这个,现在它应该要求 API 发送验证短信),这就是我进入 logcat:
02-04 23:11:04.492 820-820/com.theroom.TestProject V/Zygote﹕ Switching descriptor 34 to /dev/null
02-04 23:11:04.492 820-820/com.theroom.TestProject V/Zygote﹕ Switching descriptor 9 to /dev/null
02-04 23:11:04.492 820-820/com.theroom.TestProject D/dalvikvm﹕ Late-enabling CheckJNI
02-04 23:11:04.512 820-820/com.theroom.TestProject I/dalvikvm﹕ Enabling JNI app bug workarounds for target SDK version 10...
02-04 23:11:04.552 820-820/com.theroom.TestProject D/ActivityThread﹕ handleBindApplication:com.theroom.TestProject
02-04 23:11:04.552 820-820/com.theroom.TestProject D/ActivityThread﹕ setTargetHeapUtilization:0.75
02-04 23:11:04.552 820-820/com.theroom.TestProject D/ActivityThread﹕ setTargetHeapMinFree:2097152
02-04 23:11:04.802 820-820/com.theroom.TestProject I/Timeline﹕ Timeline: Activity_idle id: android.os.BinderProxy@418911a8 time:412893749
02-04 23:11:14.212 820-820/com.theroom.TestProject D/AndroidRuntime﹕ Shutting down VM
02-04 23:11:14.212 820-820/com.theroom.TestProject W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x415dedb8)
02-04 23:11:14.222 820-820/com.theroom.TestProject E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.theroom.TestProject, PID: 820
java.lang.IllegalStateException: Could not execute method of the activity
at android.view.View.onClick(View.java:3830)
at android.view.View.performClick(View.java:4445)
at android.view.View$PerformClick.run(View.java:18446)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5146)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at android.view.View.onClick(View.java:3825)
at android.view.View.performClick(View.java:4445)
at android.view.View$PerformClick.run(View.java:18446)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5146)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
at libcore.io.IoBridge.connect(IoBridge.java:112)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:460)
at java.net.Socket.connect(Socket.java:833)
at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
at com.theroom.TestProject.TestActivity.ToastPhoneNumber(TestActivity.java:73)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at android.view.View.onClick(View.java:3825)
at android.view.View.performClick(View.java:4445)
at android.view.View$PerformClick.run(View.java:18446)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5146)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
at dalvik.system.NativeStart.main(Native Method)
你能帮我找出问题所在吗?我发现 Java 的异常很难诊断。它不像 PHP 使用起来那么简单和直观,例如 :(
Caused by: android.os.NetworkOnMainThreadException
您正在尝试从主线程进行网络调用,这在 android 中是不允许的。
从方法 ToastPhoneNumber(View view)
MyTask task = new MyTask()
task.execute();
和任务:
public class MyTask extends AsyncTask<String, Void, String> {
MyTask() {}
@Override
protected Boolean doInBackground(String... params) {
try {
// REST CALL
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
@Override
protected void onPostExecute(final Boolean success) {
if (success) {
// handle post execute
}
}
@Override
protected void onCancelled() {
}
}
这应该有用,希望对您有所帮助!