Android URL和HTTP Post错误
Android URL和HTTP Post错误
当我尝试使用HTTP POST将数据传递给服务器时,遇到了问题。我想将这些数据插入到数据库中。但是,当我测试时,错误显示为“很抱歉,...已停止工作。”
TestActivity.java
public class TestActivity extends AppCompatActivity { ArrayListcartList; String URL_SEND; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); cartList = new ArrayList<>(); URL_SEND = "http://192.168.56.1/api.php"; new SendOrder().execute(); } class SendOrder extends AsyncTask { @Override protected Void doInBackground(Void... params) { Cart cart1 = new Cart("1", 3); cartList.add(cart1); Cart cart2 = new Cart("2", 2); cartList.add(cart2); try { URL url = new URL(URL_SEND); HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection(); httpURLConnection.setDoOutput(true); httpURLConnection.setRequestMethod("POST"); httpURLConnection.setRequestProperty("Content-Type", "application/json"); httpURLConnection.connect(); JSONObject jsonObject = new JSONObject(); jsonObject.put("idUser", "1"); jsonObject.put("total", 50000); jsonObject.put("cartArray", new JSONArray(cartList)); jsonObject.put("key", "12345"); OutputStreamWriter writer = new OutputStreamWriter(httpURLConnection.getOutputStream()); writer.write(jsonObject.toString()); writer.flush(); Toast.makeText(TestActivity.this, "订单成功", Toast.LENGTH_LONG).show(); cartList.clear(); } catch (Exception e) { Toast.makeText(TestActivity.this, "服务器错误", Toast.LENGTH_LONG).show(); } return null; } } }
Cart.java
public class Cart { private String idMenu; private int quantity = 0; public Cart() { } public Cart(String idMenu, int quantity){ this.idMenu = idMenu; this.quantity = quantity; } public String getIdMenu(){ return idMenu; } public void setIdMenu(String idMenu) { this.idMenu = idMenu; } public int getQuantity() { return quantity; } public void setQuantity(int quantity) { this.quantity = quantity; } }
api.php
prepare("INSERT INTO order(user_id, total, status_order, time) VALUES(:idUser, :total, :status, :waktu)"); $res = $sth->execute(array( 'idUser' => $user_id, 'total' => $total, 'status' => $status, 'waktu' => date() )); $id = $dbh->lastInsertId(); foreach ($cartArray as $cart) { $idProduct = $cart->idMenu; $qty = $cart->quantity; $sth = $dbh->prepare('INSERT INTO order_detail(id_order, id_product, qty) VALUES (:idOrder, :idProduct, :qty)'); $res = $sth->execute(array( 'idOrder' => $id, 'idProduct' => $idProduct, 'qty' => $qty )); } } } ?>
似乎URL本身有问题。当我只运行URL url = new URL(URL_SEND);
时,出现了相同的错误。我不知道为什么这段代码不起作用。
编辑
这是我得到的错误。
FATAL EXCEPTION: AsyncTask #1 Process: com.catering.catering, PID: 5219 java.lang.RuntimeException: An error occurred while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:309) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354) at java.util.concurrent.FutureTask.setException(FutureTask.java:223) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818) Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() at android.os.Handler.(Handler.java:200) at android.os.Handler. (Handler.java:114) at android.widget.Toast$TN. (Toast.java:345) at android.widget.Toast. (Toast.java:101) at android.widget.Toast.makeText(Toast.java:259) at com.catering.catering.TestActivity$SendOrder.doInBackground(TestActivity.java:90) at com.catering.catering.TestActivity$SendOrder.doInBackground(TestActivity.java:57) at android.os.AsyncTask$2.call(AsyncTask.java:295) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818)
问题的原因是在doInBackground()方法中进行了UI操作,而在该方法中是不允许进行UI操作的。解决方法是将这些UI操作移到onPostExecute()方法中进行。
具体的解决步骤如下:
1. 从doInBackground()方法中移除以下两行代码:
Toast.makeText(TestActivity.this, "Order success", Toast.LENGTH_LONG).show();
和
Toast.makeText(TestActivity.this, "Server error", Toast.LENGTH_LONG).show();
2. 将这些UI操作移到onPostExecute()方法中进行。
3. 可以参考以下链接了解更多关于在AsyncTask中进行UI操作的信息:https://stackoverflow.com/a/18948837/6756514
4. 如果想在catch块中显示第二个Toast消息,可以将AsyncTask的泛型改为AsyncTask<Void, Void, String>,并在doInBackground()方法中使用return语句返回需要显示的文本。
希望以上解决方法能够帮助到你。
问题原因:在 doInBackground() 方法中进行了 UI 相关的操作,导致出现错误。
解决方法:在 doInBackground() 方法中移除显示 Toast 的代码,并根据实现情况返回一个 Boolean 对象来判断 POST 请求是否成功。
public class SendOrder extends AsyncTask{ public void onPostExecute(Boolean result) { if(result != null && result) { Toast.makeText(TestActivity.this, "Order success", Toast.LENGTH_LONG).show(); } else { Toast.makeText(TestActivity.this, "Order error", Toast.LENGTH_LONG).show(); } } protected Boolean doInBackground(Void... params) { Cart cart1 = new Cart("1", 3); cartList.add(cart1); Cart cart2 = new Cart("2", 2); cartList.add(cart2); try { URL url = new URL(URL_SEND); HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection(); httpURLConnection.setDoOutput(true); httpURLConnection.setRequestMethod("POST"); httpURLConnection.setRequestProperty("Content-Type", "application/json"); httpURLConnection.connect(); JSONObject jsonObject = new JSONObject(); jsonObject.put("idUser", "1"); jsonObject.put("total", 50000); jsonObject.put("cartArray", new JSONArray(cartList)); jsonObject.put("key", "12345"); OutputStreamWriter writer = new OutputStreamWriter(httpURLConnection.getOutputStream()); writer.write(jsonObject.toString()); writer.flush(); cartList.clear(); return true; } catch (Exception e) { // 记录错误日志的代码 return false; } } }
以上代码已经修复了问题。感谢这个答案,它展示了 POST 请求是否成功。