android exception android-asynctask database-connection fatal-error

cómo solucionarlo: EXCEPCIÓN FATAL: main android.os.NetworkOnMainThreadException



android-asynctask database-connection (2)

Esta pregunta ya tiene una respuesta aquí:

Estoy teniendo probelmas ejecutando mi código en la versión de Android 18. He usado AsyncTask pero sigo recibiendo un error, por favor ayuda. Soy un novato en programación así que disculpe mis errores

package com.example.androidhive; import java.util.ArrayList; import java.util.List; import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; public class EditProductActivity extends Activity { EditText txtName; EditText txtPrice; EditText txtDesc; EditText txtCreatedAt; Button btnSave; Button btnDelete; String pid; // Progress Dialog private ProgressDialog pDialog; // JSON parser class JSONParser jsonParser = new JSONParser(); // single product url private static final String url_product_detials = "http://10.0.2.2/android_connect/get_product_details.php"; // url to update product private static final String url_update_product = "http://10.0.2.2/android_connect/update_product.php"; // url to delete product private static final String url_delete_product = "http://10.0.2.2/android_connect/delete_product.php"; // JSON Node names private static final String TAG_SUCCESS = "success"; private static final String TAG_PRODUCT = "product"; private static final String TAG_PID = "pid"; private static final String TAG_NAME = "name"; private static final String TAG_PRICE = "price"; private static final String TAG_DESCRIPTION = "description"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.edit_product); // save button btnSave = (Button) findViewById(R.id.btnSave); btnDelete = (Button) findViewById(R.id.btnDelete); // getting product details from intent Intent i = getIntent(); // getting product id (pid) from intent pid = i.getStringExtra(TAG_PID); // Getting complete product details in background thread new GetProductDetails().execute(); // save button click event btnSave.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { // starting background task to update product new SaveProductDetails().execute(); } }); // Delete button click event btnDelete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { // deleting product in background thread new DeleteProduct().execute(); } }); } /** * Background Async Task to Get complete product details * */ class GetProductDetails extends AsyncTask<String, String, String> { /** * Before starting background thread Show Progress Dialog * */ @Override protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(EditProductActivity.this); pDialog.setMessage("Loading product details. Please wait..."); pDialog.setIndeterminate(false); pDialog.setCancelable(true); pDialog.show(); } /** * Getting product details in background thread * */ protected String doInBackground(String... params) { // updating UI from Background Thread runOnUiThread(new Runnable() { public void run() { // Check for success tag int success; try { // Building Parameters List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("pid", pid)); // getting product details by making HTTP request // Note that product details url will use GET request JSONObject json = jsonParser.makeHttpRequest( url_product_detials, "GET", params); // check your log for json response Log.d("Single Product Details", json.toString()); // json success tag success = json.getInt(TAG_SUCCESS); if (success == 1) { // successfully received product details JSONArray productObj = json .getJSONArray(TAG_PRODUCT); // JSON Array // get first product object from JSON Array JSONObject product = productObj.getJSONObject(0); setContentView(R.layout.edit_product); // product with this pid found // Edit Text txtName = (EditText) findViewById(R.id.inputName); txtPrice = (EditText) findViewById(R.id.inputPrice); txtDesc = (EditText) findViewById(R.id.inputDesc); // display product data in EditText txtName.setText(product.getString(TAG_NAME)); txtPrice.setText(product.getString(TAG_PRICE)); txtDesc.setText(product.getString(TAG_DESCRIPTION)); }else{ // product with pid not found } } catch (JSONException e) { e.printStackTrace(); } } }); return null; } /** * After completing background task Dismiss the progress dialog * **/ protected void onPostExecute(String file_url) { // dismiss the dialog once got all details pDialog.dismiss(); } } /** * Background Async Task to Save product Details * */ class SaveProductDetails extends AsyncTask<String, String, String> { /** * Before starting background thread Show Progress Dialog * */ @Override protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(EditProductActivity.this); pDialog.setMessage("Saving product ..."); pDialog.setIndeterminate(false); pDialog.setCancelable(true); pDialog.show(); } /** * Saving product * */ protected String doInBackground(String... args) { // getting updated data from EditTexts String name = txtName.getText().toString(); String price = txtPrice.getText().toString(); String description = txtDesc.getText().toString(); // Building Parameters List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair(TAG_PID, pid)); params.add(new BasicNameValuePair(TAG_NAME, name)); params.add(new BasicNameValuePair(TAG_PRICE, price)); params.add(new BasicNameValuePair(TAG_DESCRIPTION, description)); // sending modified data through http request // Notice that update product url accepts POST method JSONObject json = jsonParser.makeHttpRequest(url_update_product, "POST", params); // check json success tag try { int success = json.getInt(TAG_SUCCESS); if (success == 1) { // successfully updated Intent i = getIntent(); // send result code 100 to notify about product update setResult(100, i); finish(); } else { // failed to update product } } catch (JSONException e) { e.printStackTrace(); } return null; } /** * After completing background task Dismiss the progress dialog * **/ protected void onPostExecute(String file_url) { // dismiss the dialog once product updated pDialog.dismiss(); } } /***************************************************************** * Background Async Task to Delete Product * */ class DeleteProduct extends AsyncTask<String, String, String> { /** * Before starting background thread Show Progress Dialog * */ @Override protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(EditProductActivity.this); pDialog.setMessage("Deleting Product..."); pDialog.setIndeterminate(false); pDialog.setCancelable(true); pDialog.show(); } /** * Deleting product * */ protected String doInBackground(String... args) { // Check for success tag int success; try { // Building Parameters List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("pid", pid)); // getting product details by making HTTP request JSONObject json = jsonParser.makeHttpRequest( url_delete_product, "POST", params); // check your log for json response Log.d("Delete Product", json.toString()); // json success tag success = json.getInt(TAG_SUCCESS); if (success == 1) { // product successfully deleted // notify previous activity by sending code 100 Intent i = getIntent(); // send result code 100 to notify about product deletion setResult(100, i); finish(); } } catch (JSONException e) { e.printStackTrace(); } return null; } /** * After completing background task Dismiss the progress dialog * **/ protected void onPostExecute(String file_url) { // dismiss the dialog once product deleted pDialog.dismiss(); } } }

el error que estoy recibiendo es:

10-27 17:01:52.858: E/AndroidRuntime(2001): FATAL EXCEPTION: main 10-27 17:01:52.858: E/AndroidRuntime(2001): android.os.NetworkOnMainThreadException 10-27 17:01:52.858: E/AndroidRuntime(2001): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1133) 10-27 17:01:52.858: E/AndroidRuntime(2001): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84) 10-27 17:01:52.858: E/AndroidRuntime(2001): at libcore.io.IoBridge.connectErrno(IoBridge.java:127) 10-27 17:01:52.858: E/AndroidRuntime(2001): at libcore.io.IoBridge.connect(IoBridge.java:112) 10-27 17:01:52.858: E/AndroidRuntime(2001): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192) 10-27 17:01:52.858: E/AndroidRuntime(2001): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459) 10-27 17:01:52.858: E/AndroidRuntime(2001): at java.net.Socket.connect(Socket.java:842) 10-27 17:01:52.858: E/AndroidRuntime(2001): at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119) 10-27 17:01:52.858: E/AndroidRuntime(2001): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144) 10-27 17:01:52.858: E/AndroidRuntime(2001): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 10-27 17:01:52.858: E/AndroidRuntime(2001): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 10-27 17:01:52.858: E/AndroidRuntime(2001): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360) 10-27 17:01:52.858: E/AndroidRuntime(2001): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 10-27 17:01:52.858: E/AndroidRuntime(2001): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 10-27 17:01:52.858: E/AndroidRuntime(2001): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 10-27 17:01:52.858: E/AndroidRuntime(2001): at com.example.androidhive.JSONParser.makeHttpRequest(JSONParser.java:62) 10-27 17:01:52.858: E/AndroidRuntime(2001): at com.example.androidhive.EditProductActivity$GetProductDetails$1.run(EditProductActivity.java:137) 10-27 17:01:52.858: E/AndroidRuntime(2001): at android.os.Handler.handleCallback(Handler.java:730) 10-27 17:01:52.858: E/AndroidRuntime(2001): at android.os.Handler.dispatchMessage(Handler.java:92) 10-27 17:01:52.858: E/AndroidRuntime(2001): at android.os.Looper.loop(Looper.java:137) 10-27 17:01:52.858: E/AndroidRuntime(2001): at android.app.ActivityThread.main(ActivityThread.java:5103) 10-27 17:01:52.858: E/AndroidRuntime(2001): at java.lang.reflect.Method.invokeNative(Native Method) 10-27 17:01:52.858: E/AndroidRuntime(2001): at java.lang.reflect.Method.invoke(Method.java:525) 10-27 17:01:52.858: E/AndroidRuntime(2001): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 10-27 17:01:52.858: E/AndroidRuntime(2001): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 10-27 17:01:52.858: E/AndroidRuntime(2001): at dalvik.system.NativeStart.main(Native Method)

y el diseño xml de diseño se ve así:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <!-- Name Label --> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="10dip" android:paddingRight="10dip" android:paddingTop="10dip" android:text="@string/Product_Name2" android:textSize="17sp" /> <!-- Input Name --> <EditText android:id="@+id/inputName" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/inputName2" android:layout_margin="5dip" android:layout_marginBottom="15dip" android:singleLine="true"/> <!-- Price Label --> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="10dip" android:paddingRight="10dip" android:paddingTop="10dip" android:text="@string/Price2" android:textSize="17sp" /> <!-- Input Price --> <EditText android:id="@+id/inputPrice" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="5dip" android:layout_marginBottom="15dip" android:singleLine="true" android:inputType="numberDecimal"/> <!-- Description Label --> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="10dip" android:paddingRight="10dip" android:paddingTop="10dip" android:text="@string/Description2" android:textSize="17sp" /> <!-- Input description --> <EditText android:id="@+id/inputDesc" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/inputDesc2" android:layout_margin="5dip" android:layout_marginBottom="15dip" android:lines="4" android:gravity="top"/> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <!-- Button Create Product --> <Button android:id="@+id/btnSave" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/Save_Changes" /> <!-- Button Create Product --> <Button android:id="@+id/btnDelete" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/Delete" /> </LinearLayout> </LinearLayout>


En la clase GetProductDetails use solo try catch. eliminar el runOnUiThread ().


En el método doInBackground debe mantener la solicitud HTTP en la tarea de fondo y simplemente colocar la actualización de la UI en runOnUiThread . Aquí está la solución ''rápida'':

/** * Getting product details in background thread * */ protected String doInBackground(String... params) { // Check for success tag int success; try { // Building Parameters List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("pid", pid)); // getting product details by making HTTP request // Note that product details url will use GET request JSONObject json = jsonParser.makeHttpRequest( url_product_detials, "GET", params); // check your log for json response Log.d("Single Product Details", json.toString()); // json success tag success = json.getInt(TAG_SUCCESS); if (success == 1) { // successfully received product details JSONArray productObj = json .getJSONArray(TAG_PRODUCT); // JSON Array // get first product object from JSON Array final JSONObject product = productObj.getJSONObject(0); // updating UI from Background Thread runOnUiThread(new Runnable() { public void run() { setContentView(R.layout.edit_product); // product with this pid found // Edit Text txtName = (EditText) findViewById(R.id.inputName); txtPrice = (EditText) findViewById(R.id.inputPrice); txtDesc = (EditText) findViewById(R.id.inputDesc); // display product data in EditText txtName.setText(product.getString(TAG_NAME)); txtPrice.setText(product.getString(TAG_PRICE)); txtDesc.setText(product.getString(TAG_DESCRIPTION)); } }); }else{ // product with pid not found } } catch (JSONException e) { e.printStackTrace(); } return null; }

La solución recomendada es cambiar el método doInBackground para devolver el resultado de la solicitud y actualizar la IU en onPostExecute siguiente manera:

/** * Background Async Task to Get complete product details * */ class GetProductDetails extends AsyncTask<String, String, JSONObject> { /** * Before starting background thread Show Progress Dialog * */ @Override protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(EditProductActivity.this); pDialog.setMessage("Loading product details. Please wait..."); pDialog.setIndeterminate(false); pDialog.setCancelable(true); pDialog.show(); } /** * Getting product details in background thread * */ protected JSONObject doInBackground(String... params) { JSONObject product = null; // Check for success tag int success; try { // Building Parameters List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("pid", pid)); // getting product details by making HTTP request // Note that product details url will use GET request JSONObject json = jsonParser.makeHttpRequest( url_product_detials, "GET", params); // check your log for json response Log.d("Single Product Details", json.toString()); // json success tag success = json.getInt(TAG_SUCCESS); if (success == 1) { // successfully received product details JSONArray productObj = json .getJSONArray(TAG_PRODUCT); // JSON Array // get first product object from JSON Array product = productObj.getJSONObject(0); }else{ // product with pid not found } } catch (JSONException e) { e.printStackTrace(); } return product; } /** * After completing background task Dismiss the progress dialog * **/ protected void onPostExecute(JSONObject product) { if (product != null) { setContentView(R.layout.edit_product); // product with this pid found // Edit Text txtName = (EditText) findViewById(R.id.inputName); txtPrice = (EditText) findViewById(R.id.inputPrice); txtDesc = (EditText) findViewById(R.id.inputDesc); // display product data in EditText txtName.setText(product.getString(TAG_NAME)); txtPrice.setText(product.getString(TAG_PRICE)); txtDesc.setText(product.getString(TAG_DESCRIPTION)); } // dismiss the dialog once got all details pDialog.dismiss(); } }