I'm trying a simple example : http://www.vogella.com/articles/AndroidJSON/article.html
But got an error .. Can anyone tell me why I get this error : http://puu.sh/1mGz1
use AsyncTask for making server request from UI Thread so change your code as:
///Your code...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new LongOperation().execute("");
}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
//call readtwitterFeed() method here
String readtwitterFeed=readtwitterFeed();
return readtwitterFeed;
}
#Override
protected void onPostExecute(String result) {
try {
JSONArray jsonArray = new JSONArray(result);
Log.i(ParseJSON.class.getName(),
"Number of entries " + jsonArray.length());
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Log.i(ParseJSON.class.getName(), jsonObject.getString("text"));
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
You are trying to make data request on the main thread. Use AsyncTask to do it.
Or add this 2 line in the onCreate() method to bypass it.
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
I recommend using asynctask though.
Related
I have implemented AsyncTask like this in my code. Can you tell me if I used AsyncTask correctly? Thanks.
protected class AsyncTranslator extends AsyncTask<String, JSONObject, String>
{
#Override
protected String doInBackground(String... params) {
String mymeaning = null;
RestAPI api = new RestAPI();
try
{
JSONObject jsonObj = api.GetMeaning(params[0]);
mymeaning = jsonObj.toString();
}
catch (Exception e)
{
Log.d("Error", e.getMessage());
}
return mymeaning ;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(context, "Please wait.", Toast.LENGTH_SHORT).show();
}
#Override
protected void onPostExecute(String mymeaning) {
Log.d("onPostExecute", null);
Intent i = new Intent(SendMeaningActivity.this, ShowMeaningActivity.class);
i.putExtra("meaning", mymeaning);
startActivity(i);
}
}
Yes you used it correctly.
Fot API call, think to use library like Retrofit. It will make your life easier.
I'm trying to fetch data from server in saving in SQLite database through Async task on Splash. i have multiple tables on server and need to fetch one after another. I'm trying this way
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork()
.penaltyLog().build());
url = getResources().getString(R.string.url);
db = new SQLCont(context);
new asyn_Task1(Splash.this).execute();
}
public class asyn_Task1 extends AsyncTask<String, Void, Boolean> {
public asyn_Task1(Splash activiy) {
context = activiy;
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
new asyn_Task2(Splash.this).execute();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressdialog = new ProgressDialog(Splash.this);
progressdialog.setTitle("Processing....");
progressdialog.setMessage("Please Wait.....1 /10");
progressdialog.setCancelable(false);
progressdialog.show();
}
#Override
protected Boolean doInBackground(String... params) {
postParameters.add(new BasicNameValuePair("001", data));
try {
CustomHttpClient.executeHttpGet("001");
} catch (Exception e1) {
e1.printStackTrace();
}
String response = null;
// call executeHttpPost method passing necessary parameters
try {
response = CustomHttpClient.executeHttpPost(
url,
postParameters);
// store the result returned by PHP script that runs
// MySQL query
String result = response.toString();
// parse json data
try {
JSONArray jArray = new JSONArray(result);
for (int i = 0; i < jArray.length(); i++) {
JSONObject json_data = jArray.getJSONObject(i);
id = json_data.getString("id");
st_name = " " + json_data.getString("name");
st_contact = json_data.getString("contact");
st_category = json_data.getString("Category");
st_address = json_data.getString("address");
Log.d("favourite_data", "" + id + st_name + st_contact
+ st_category + st_address);
db.adddata_hospital(context, st_name,st_contact,
st_category, st_address);
}
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data " + e.toString());
}
} catch (Exception e) {
Log.e("log_tag", "Error in http connection!!" + e.toString());
}
return null;
}
}
public class asyn_Task2 extends AsyncTask<String, Void, Boolean> {
public asyn_Task2(Splash activiy) {
context = activiy;
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
new asyn_Task3(Splash.this).execute();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Boolean doInBackground(String... params) {
// some stuff here
}
return null;
}
}
public class asyn_Task3 extends AsyncTask<String, Void, Boolean> {
public asyn_blood_Group(Splash activiy) {
context = activiy;
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
progressdialog.dismiss();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Boolean doInBackground(String... params) {
// some stuff here
}
return null;
}
}
problem is that data is added for asyn_Task1 it repeated every time
expected out put
abc def ghi
jkl mno pqr
mno pqr stu
But getting output
abc def ghi
abc def ghi
abc def ghi
You will get your data based on your query. If you always execute same query then you will always get same data.
And from my point of view if possible single AsyncTask for that purpose. when all the query is completed then onpostExecute() callback will fired.
I have a problem with my adapter for my listview, i don't know where i have to add notifyDataSetChanged() in my code always if i run this code in logcat is coming a error:
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131165276, class android.widget.ListView)]
my asynctask:
class UpdateData extends AsyncTask<Void, Void, JSONArray> {
String result = "";
JSONArray jArray = null;
#Override
protected void onPostExecute(JSONArray result) {
super.onPostExecute(result);
adapter.addAll(deptList);
adapter.notifyDataSetChanged();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected JSONArray doInBackground(Void... arg0) {
....
try {
JSONArray array = new JSONArray(result);
for (int i = 0; i < array.length(); i++) {
JSONObject j = array.getJSONObject(i);
EventCalendarStrings d = new EventCalendarStrings();
d.name = j.optString("name", "");
d.kategorie = j.optString("Art", "");
deptList.add(d);
}
} catch (JSONException e) {
Log.e("log_tag", "No connection " + e.toString());
}
}
return jArray;
}
It goes in onPostExecute() because it is executed on the UI thread. Calling it in doInBackground() will result in that exception.
Try this
#Override
protected void onPostExecute(JSONArray result) {
super.onPostExecute(result);
runOnUiThread(new Runnable(){
public void run(){
adapter.addAll(deptList);
adapter.notifyDataSetChanged();
}
});
}
or
#Override
protected void onPostExecute(JSONArray result) {
super.onPostExecute(result);
runOnUiThread(new Runnable(){
public void run(){
adapter.addAll(deptList);
listview.setAdapater(adapter);
}
});
}
Toast is showed around of 2 times, and Json is returning fine 6 objects.
Idk if its problem of RunOnUiThread (I know that is not good for use in asyntask) or otherthing.
what other way can I use for my variable "mensaje" every time that for put a string in that I can show a Toat, maybe in OnPostExecute.
class asyncMensaje extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
String user = params[0];
ArrayList<NameValuePair> envioDato = new ArrayList<NameValuePair>();
envioDato.add(new BasicNameValuePair("rut", user));
JSONArray jdata2 = post.getserverdata(envioDato, URL_connectFechas);
if (jdata2 != null && jdata2.length() > 0) {
JSONObject json_data; // creamos un objeto JSON
for (int i = 0; i < jdata2.length(); i++) {
try {
json_data = jdata2.getJSONObject(i);
mensaje = json_data.getString("mensaje");
Log.e("Info: ", "" + mensaje);
} catch (JSONException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), mensaje, Toast.LENGTH_LONG).show();
}
});
}
}
return null;
}
protected void onPostExecute(String result) {
}
}
The ideal solution in your case is to use onProgressUpdate together with sequencing of Toasts. Refer to this answer for doing the latter.
class asyncMensaje extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
//....
for (int i = 0; i < jdata2.length(); i++) {
//..
publishProgress(mensaje);
}
}
#Override
protected void onProgressUpdate(String... progress) {
//code for showing Toast
}
}
Use onPostExecute method for processing data after getting from webservice in doInBackground instead of using runOnUiThread in doInBackground which run on different Thread. do it as:
#Override
protected String doInBackground(String... params) {
String user = params[0];
ArrayList<NameValuePair> envioDato = new ArrayList<NameValuePair>();
envioDato.add(new BasicNameValuePair("rut", user));
JSONArray jdata2 = post.getserverdata(envioDato, URL_connectFechas);
return jdata2.toString();
}
#Override
protected void onPostExecute(String result) {
JSONArray jdata2=new JSONArray(result);
// parse JSONArray here and show Toast...
}
I'm new to Android development and I'm trying to code a little app which allows me to grab an external JSON file and parse it. I got this to work, however it wont work if I try to execute it in the background as an AsyncTask. Eclipse gives me the error
The method findViewById(int) is undefined for the type LongOperation
in this line:
TextView txtView1 = (TextView)findViewById(R.id.TextView01);
Here is my code:
public class Main extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new LongOperation().execute();
}
}
class LongOperation extends AsyncTask<String, Void, String> {
private final Context LongOperation = null;
#Override
protected String doInBackground(String... params) {
try {
URL json = new URL("http://www.corps-marchia.de/jsontest.php");
URLConnection tc = json.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(tc.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
JSONArray ja = new JSONArray(line);
JSONObject jo = (JSONObject) ja.get(0);
TextView txtView1 = (TextView)findViewById(R.id.TextView01);
txtView1.setText(jo.getString("text") + " - " + jo.getString("secondtest"));
}
} catch (MalformedURLException e) {
Toast.makeText(this.LongOperation, "Malformed URL Exception: " + e, Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(this.LongOperation, "IO Exception: " + e, Toast.LENGTH_LONG).show();
} catch (JSONException e) {
Toast.makeText(this.LongOperation, "JSON Exception: " + e, Toast.LENGTH_LONG).show();
}
return null;
}
#Override
protected void onPostExecute(String result) {
}
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
ProgressDialog pd = new ProgressDialog(LongOperation);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("Working...");
pd.setIndeterminate(true);
pd.setCancelable(false);
}
}
Any ideas on how to fix this?
Here is what you should do to make it work as you want. Use onPostExecude()
public class Main extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new LongOperation(this).execute();
}
}
class LongOperation extends AsyncTask<String, Void, String> {
private Main longOperationContext = null;
public LongOperation(Main context) {
longOperationContext = context;
Log.v("LongOper", "Konstuktor");
}
#Override
protected String doInBackground(String... params) {
Log.v("doInBackground", "inside");
StringBuilder sb = new StringBuilder();
try {
URL json = new URL("http://www.corps-marchia.de/jsontest.php");
URLConnection tc = json.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(tc.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
JSONArray ja = new JSONArray(line);
JSONObject jo = (JSONObject) ja.get(0);
Log.v("line = ", "jo.getString() ="+jo.getString("text"));
sb.append(jo.getString("text") + " - " + jo.getString("secondtest")).append("\n");
}
} catch (MalformedURLException e) {
e.printStackTrace();
Log.v("Error", "URL exc");
} catch (IOException e) {
e.printStackTrace();
Log.v("ERROR", "IOEXECPTOIn");
} catch (JSONException e) {
e.printStackTrace();
Log.v("Error", "JsonException");
}
String result = sb.toString();
return result;
}
#Override
protected void onPostExecute(String result) {
Log.v("onPostExe", "result = "+result);
TextView txtView1 = (TextView)longOperationContext.findViewById(R.id.textView01);
txtView1.setText(result);
}
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
ProgressDialog pd = new ProgressDialog(longOperationContext);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("Working...");
pd.setIndeterminate(true);
pd.setCancelable(false);
}
}
The implementation of AsyncTask in one of the other answers is flawed. The progress dialog is being created every time within publishProgress, and the reference to the dialog is not visible outside the method. Here is my attempt:
public class Main extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new LongOperation().execute();
}
class LongOperation extends AsyncTask<String, Void, String> {
ProgressDialog pd = null;
TextView tv = null;
#Override
protected void onPreExecute(){
tv = Main.this.findViewById(R.id.textvewid);
pd = new ProgressDialog(Main.this);
pd.setMessage("Working...");
// setup rest of progress dialog
}
#Override
protected String doInBackground(String... params) {
//perform existing background task
return result;
}
#Override
protected void onPostExecute(String result){
pd.dismiss();
tv.setText(result);
}
}
}
You are trying to do something which won't work. First of all you are inside of a class that extends AsyncTask so you won't have that method available as it is a method of the class Activity.
The second problem is that you are trying to do UI stuff in a method that is not synchronized with the UI thread. That is nothing you would want to do.
Process your JSON response in the doInBackground method and pass the result to the onPostExecute method where you will be able to handle UI stuff as it is synchronized with the UI thread.
The current setup you have will not make it easier for you to handle what you are trying to do anyway. You could make your LongOperation class a private class of your Activity class and define the TextView as a instance member. Grab it off the layout using findViewById inside of your OnCreate and modify (set text or whatever) inside the onPostExecute method of your AsyncTask.
I hope it is somewhat clear what I meant.
findViewById is method in Activity class. You should pass instance of your activity to your LongOperation when you create it. Then use that instance to call findViewById.