Reputation: 103
I am trying to run my app on a 3.2 Android Device (Honeycomb).
Unfortunately, my app crashes whenever I try to edit one of the objects listed in my app using EditCaseActivity
. Logcat seems to tell me that StrictMode
is causing the crash, but I'm already using AsyncTask
.
Any form of help is greatly appreciated! :)
My friend suspects that it has something to do with RunOnUiThread
, but trying to edit away the RunOnUiThread
of the code brings me errors with 'params' in lines 126 and 127.
EditCaseActivity.java
package com.pivestigator.cases;
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 com.pivestigator.JSONParser;
import com.pivestigator.R;
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 EditCaseActivity extends Activity {
EditText txtCaseName;
EditText txtCaseUser;
EditText txtCaseCategory;
EditText txtCreatedAt;
Button btnSave;
Button btnDelete;
String cid;
// Progress Dialog
private ProgressDialog pDialog;
// JSON parser class
JSONParser jsonParser = new JSONParser();
// single case url
private static final String url_case_details = "http://nsecure.5gbfree.com/PIvestigator/case/get_case_details.php";
// url to update case
private static final String url_update_case = "http://nsecure.5gbfree.com/PIvestigator/case/update_case.php";
// url to delete case
private static final String url_delete_case = "http://nsecure.5gbfree.com/PIvestigator/case/delete_case.php";
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_CASE = "case";
private static final String TAG_CID = "cid";
private static final String TAG_CASE_NAME = "case_name";
private static final String TAG_CASE_USER = "case_user";
private static final String TAG_CASE_CATEGORY = "case_category";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_case);
// save button
btnSave = (Button) findViewById(R.id.btnSave);
btnDelete = (Button) findViewById(R.id.btnDelete);
// getting case details from intent
Intent i = getIntent();
// getting case id (cid) from intent
cid = i.getStringExtra(TAG_CID);
// Getting complete case details in background thread
new GetCaseDetails().execute();
// save button click event
btnSave.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
// starting background task to update case
new SaveCaseDetails().execute();
}
});
// Delete button click event
btnDelete.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
// deleting case in background thread
new DeleteCase().execute();
}
});
}
/**
* Background Async Task to Get complete case details
* */
class GetCaseDetails extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(EditCaseActivity.this);
pDialog.setMessage("Loading case details. Please stare at spinner to increase loading speed...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
/**
* Getting case 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("cid", cid));
// getting case details by making HTTP request
// Note that case details url will use GET request
JSONObject json = jsonParser.makeHttpRequest(
url_case_details, "GET", params);
// check your log for json response
Log.d("Single Case Details", json.toString());
// json success tag
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// successfully received case details
JSONArray caseObj = json
.getJSONArray(TAG_CASE); // JSON Array
// get first case object from JSON Array
JSONObject cases = caseObj.getJSONObject(0);
// case with this cid found
// Edit Text
txtCaseName = (EditText) findViewById(R.id.inputCaseName);
txtCaseUser = (EditText) findViewById(R.id.inputCaseUser);
txtCaseCategory = (EditText) findViewById(R.id.inputCaseCategory);
// display case data in EditText
txtCaseName.setText(cases.getString(TAG_CASE_NAME));
txtCaseUser.setText(cases.getString(TAG_CASE_USER));
txtCaseCategory.setText(cases.getString(TAG_CASE_CATEGORY));
}else{
// case with cid 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 case Details
* */
class SaveCaseDetails extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(EditCaseActivity.this);
pDialog.setMessage("Saving case ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
/**
* Saving case
* */
protected String doInBackground(String... args) {
// getting updated data from EditTexts
String case_name = txtCaseName.getText().toString();
String case_user = txtCaseUser.getText().toString();
String case_category = txtCaseCategory.getText().toString();
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair(TAG_CID, cid));
params.add(new BasicNameValuePair(TAG_CASE_NAME, case_name));
params.add(new BasicNameValuePair(TAG_CASE_USER, case_user));
params.add(new BasicNameValuePair(TAG_CASE_CATEGORY, case_category));
// sending modified data through http request
// Notice that update case url accepts POST method
JSONObject json = jsonParser.makeHttpRequest(url_update_case,
"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 case update
setResult(100, i);
finish();
} else {
// failed to update case
}
} 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 case updated
pDialog.dismiss();
}
}
/*****************************************************************
* Background Async Task to Delete Case
* */
class DeleteCase extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(EditCaseActivity.this);
pDialog.setMessage("Deleting Case...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
/**
* Deleting case
* */
protected String doInBackground(String... args) {
// Check for success tag
int success;
try {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("cid", cid));
// getting case details by making HTTP request
JSONObject json = jsonParser.makeHttpRequest(
url_delete_case, "POST", params);
// check your log for json response
Log.d("Delete Case", json.toString());
// json success tag
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// case successfully deleted
// notify previous activity by sending code 100
Intent i = getIntent();
// send result code 100 to notify about case 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 case deleted
pDialog.dismiss();
}
}
}
Logcat Output:
09-05 15:13:17.250: D/All Cases:(4519): {"cases":[{"case_name":"1111","created_at":"2012-07-23 20:35:05","updated_at":"2012-07-24 01:08:41","case_category":"111111111111111","case_user":"1111111","cid":"10"},{"case_name":"c","created_at":"2012-07-23 23:12:36","updated_at":"0000-00-00 00:00:00","case_category":"action2","case_user":"a","cid":"11"},{"case_name":"Klara","created_at":"2012-07-23 23:15:30","updated_at":"0000-00-00 00:00:00","case_category":"i dont know wha","case_user":"Rara","cid":"12"},{"case_name":"chicken","created_at":"2012-07-24 00:58:43","updated_at":"2012-07-24 01:07:24","case_category":"DERPID 2","case_user":"Sherlock","cid":"13"},{"case_name":"derpy\t","created_at":"2012-07-24 01:13:24","updated_at":"2012-07-24 01:29:04","case_category":"blkchicken.chic","case_user":"Sherlock","cid":"14"}],"success":1}
09-05 15:13:33.340: D/AndroidRuntime(4519): Shutting down VM
09-05 15:13:33.340: W/dalvikvm(4519): threadid=1: thread exiting with uncaught exception (group=0x400ee760)
09-05 15:13:33.340: E/AndroidRuntime(4519): FATAL EXCEPTION: main
09-05 15:13:33.340: E/AndroidRuntime(4519): android.os.NetworkOnMainThreadException
09-05 15:13:33.340: E/AndroidRuntime(4519): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1077)
09-05 15:13:33.340: E/AndroidRuntime(4519): at java.net.InetAddress.lookupHostByName(InetAddress.java:477)
09-05 15:13:33.340: E/AndroidRuntime(4519): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:277)
09-05 15:13:33.340: E/AndroidRuntime(4519): at java.net.InetAddress.getAllByName(InetAddress.java:249)
09-05 15:13:33.340: E/AndroidRuntime(4519): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:136)
09-05 15:13:33.340: E/AndroidRuntime(4519): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
09-05 15:13:33.340: E/AndroidRuntime(4519): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
09-05 15:13:33.340: E/AndroidRuntime(4519): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
09-05 15:13:33.340: E/AndroidRuntime(4519): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
09-05 15:13:33.340: E/AndroidRuntime(4519): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
09-05 15:13:33.340: E/AndroidRuntime(4519): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
09-05 15:13:33.340: E/AndroidRuntime(4519): at com.pivestigator.JSONParser.makeHttpRequest(JSONParser.java:62)
09-05 15:13:33.340: E/AndroidRuntime(4519): at com.pivestigator.cases.EditCaseActivity$GetCaseDetails$1.run(EditCaseActivity.java:131)
09-05 15:13:33.340: E/AndroidRuntime(4519): at android.os.Handler.handleCallback(Handler.java:587)
09-05 15:13:33.340: E/AndroidRuntime(4519): at android.os.Handler.dispatchMessage(Handler.java:92)
09-05 15:13:33.340: E/AndroidRuntime(4519): at android.os.Looper.loop(Looper.java:132)
09-05 15:13:33.340: E/AndroidRuntime(4519): at android.app.ActivityThread.main(ActivityThread.java:4126)
09-05 15:13:33.340: E/AndroidRuntime(4519): at java.lang.reflect.Method.invokeNative(Native Method)
09-05 15:13:33.340: E/AndroidRuntime(4519): at java.lang.reflect.Method.invoke(Method.java:491)
09-05 15:13:33.340: E/AndroidRuntime(4519): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
09-05 15:13:33.340: E/AndroidRuntime(4519): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
09-05 15:13:33.340: E/AndroidRuntime(4519): at dalvik.system.NativeStart.main(Native Method)
09-05 15:13:35.360: I/dalvikvm(4519): threadid=4: reacting to signal 3
09-05 15:13:35.370: I/dalvikvm(4519): Wrote stack traces to '/data/anr/traces.txt'
Upvotes: 0
Views: 597
Reputation: 45942
The mistake is in SaveCaseDetails
class.
Your are making an HTTP request (I suppose) using the function makeHttpRequest
on the UI Thread inside the doInBackground
function.
Even though the code is inside the background thread; however you are calling runOnUiThread
there which will run on the UI Thread and cause this exception.
Remove the runOnUiThread
inside the doInBackground
of the class SaveCaseDetails
.
If needed, use it only to update the UI.
Because of the params renaming, errors will occur so change their name by changing the line
protected String doInBackground(String... params)
to
protected String doInBackground(String... taskParams)
Upvotes: 0
Reputation: 2491
change this to on post execute return the json object as result and run it there
// json success tag
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// successfully received case details
JSONArray caseObj = json
.getJSONArray(TAG_CASE); // JSON Array
// get first case object from JSON Array
JSONObject cases = caseObj.getJSONObject(0);
// case with this cid found
// Edit Text
txtCaseName = (EditText) findViewById(R.id.inputCaseName);
txtCaseUser = (EditText) findViewById(R.id.inputCaseUser);
txtCaseCategory = (EditText) findViewById(R.id.inputCaseCategory);
// display case data in EditText
txtCaseName.setText(cases.getString(TAG_CASE_NAME));
txtCaseUser.setText(cases.getString(TAG_CASE_USER));
txtCaseCategory.setText(cases.getString(TAG_CASE_CATEGORY));
}else{
// case with cid not found
}
Upvotes: 0