AsyncTask onPostExecute not Outputting - android

I am not reaching an onPostExecute in an AsyncTask Class.
I call the task this way, inside an onClick in a dialog box:
new HelpfulTask().execute(passing);
Note: When I hover over the above code, I get a warning:
A generic Array of ArrayList is created for a varargs
parameter.
I am not sure what that means and if that is preventing my Task from even running?
Here is the Task Code:
protected class UnHelpfulTask extends
AsyncTask<ArrayList<String>, Void, ArrayList<String>> {
ArrayList<String> passed;
protected ArrayList<String> doInBackground(ArrayList<String>... passing) {
passed = passing[0];
String url_select = "http://www.---.com/---/bad.php";
ArrayList<NameValuePair> param = new ArrayList<NameValuePair>();
param.add(new BasicNameValuePair("item", passed.get(0)));
param.add(new BasicNameValuePair("text", passed.get(1)));
param.add(new BasicNameValuePair("category", passed.get(2)));
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url_select);
try {
httpPost.setEntity(new UrlEncodedFormEntity(param));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
// read content
is = httpEntity.getContent();
} catch (Exception e) {
Log.e("log_tag", "Error in http connection " + e.toString());
}
return null;
}
InputStream is = null;
String result = "";
protected void onPostExecute(Void v) {
Toast.makeText(getContext(), "You have voted this down!",
Toast.LENGTH_SHORT).show();
}
}
I get no errors on run and in the onPostExecute, the Toast never shows. (Note: This is an inner class inside of an ArrayAdapter.) I also added a toast to see if my ArrayList was unwrapping properly and put that in the onPostExecute but it never showed either.
How can I test to see if this Task is even running?

Change
protected void onPostExecute(Void v) {
so it is
protected void onPostExecute(ArrayList<String> arr)
Or change your AsyncTask declaration so it
extends AsyncTask<ArrayList<String>, Void, Void>
Which is the better idea since you return null in doInBackground(). The reason why you weren't getting the toast is because you were making a different method than what your AsyncTask specifies. This is why we ususally use the #Override annotation - it forces a check for actual overrides, which you need to do in classes like AsyncTasks.

Related

onPostExecute does not called

I am working on android app and facing a problem. The problem is that onPostExecute does not execute everytime event doInBackground execute successfully and return true. My code is given below. Please help me I am in big trouble.
class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {
#Override
protected void onPreExecute() {
super.onPreExecute();
msgtouser.setText("Wait we are fetching HOT DEALS...");
}
#Override
protected Boolean doInBackground(String... urls) {
Boolean retValue = false;
try {
HttpResponse response = null;
String CSRFTOKEN = "";
// Create a new HttpClient and Post Header
DefaultHttpClient httpClient = new DefaultHttpClient();
// Access POST route using CSRFTOKEN
HttpPost httppost = new HttpPost(urls[0]);
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("_token", CSRFTOKEN));
nameValuePairs.add(new BasicNameValuePair("uid", urls[1]));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
response = httpClient.execute(httppost);
} catch (Exception e) {
ccode.ErrorReporting(e);
}
int status = response.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity entity = response.getEntity();
String data = EntityUtils.toString(entity);
JSONObject jsono = new JSONObject(data);
JSONArray jarray = jsono.getJSONArray("hotdeal");
for (int i = 0; i < jarray.length(); i++) {
JSONObject object = jarray.getJSONObject(i);
HotDeals objHD = new HotDeals();
objHD.setId(object.getInt("offid"));
objHD.setName(object.getString("line1"));
objHD.setLocation(object.getString("line3"));
objHD.setDistance(object.getString("dist"));
objHD.setOffer(object.getString("line2"));
objHD.setImage(object.getString("ban"));
dealsList.add(objHD);
}
retValue = true;
}
} catch (Exception e) {
ccode.ErrorReporting(e);
}
return retValue;
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
dialog.cancel();
// adapter.notifyDataSetChanged();
if (result == false && AppConstants.ISDEBUG) {
Toast.makeText(getActivity().getApplicationContext(), "Hot Deals : Network Error", Toast.LENGTH_LONG)
.show();
} else {
if (dealsList.isEmpty()) {
msgtouser.setText("Sorry, there are no HOT DEALS for the location selected by you");
} else {
msgtouser.setVisibility(View.GONE);
ListView listview = (ListView) rootView.findViewById(R.id.listhd);
adapter = new HotDealsAdapter(HotDealsFragment.this.getActivity(), R.layout.hotdeals_row,
dealsList);
listview.setAdapter(adapter);
}
}
}
}
you don't need to call super.onPostExecute() (not sure if it could be causing problems, but isn't needed) If this isn't the problem then below...
I "think" I know what the problem is... and we've ran into it before... IF this is happening when you rotate the phone (or any other hardware change)...
Then the problem is that the return value of the doInBackground() doesn't get actually passed to the onPostExecute() and you will get a null passed in. (if the hardware change happened during the doInBackground())
However, that doesn't appear to be 'exactly' what you are having from your description. 'onPostExecute()' not running at all is odd. You should put a logcat statement as the very first thing in the method and see if that gets logged.
Because 'false' is the default value of boolean so it could be what you are describing where you don't have the 'else' part ever run, but you should be getting the toast then...
So log in two places (1) just before the return of doInBackground and (2) at the very beginning of the onPostExecute() and see if the values 'agree'

Parsing json from url in android :

I tried to request the URI bellow and parse it response a lot of ways. But I don't know what is the problem with my code below.
String url = "http://10.0.2.2/ipf/conx.php";
// Get HttpResponse Object from url.
// Get HttpEntity from Http Response Object
Log.v("Log1", "msg1");
HttpClient httpclient = new DefaultHttpClient();
HttpPost method = new HttpPost(url);
Log.v("Log1", "msg2");
HttpResponse response = httpclient.execute(method);
HttpEntity entity = response.getEntity();
if (entity != null) {
Log.v("Log2", "msg1");
} else {
Log.v("log2", "msg2");
}
When I follow my logcat print, I can see only:
log1( msg1 and 2 )
Please take some help
thanks
It takes sometime(depends upon your internet speed) to get the response from the server....!
Or you can use below class to check when the response come,
private class xyz extends AsyncTask<Void, Void, Void> {
private ProgressDialog dialog ;
private Activity mActivity;
public xyz(Activity activity)
{
this.mActivity = activity;
}
protected void onPreExecute() {
this.dialog = new ProgressDialog(mActivity);
this.dialog.setMessage("Please Wait...");
this.dialog.show();
//code which load at prefix time
}
#Override
protected Void doInBackground(Void... arg0) {
// make code which you want in background
String url = "http://10.0.2.2/ipf/conx.php";
// Get HttpResponse Object from url.
// Get HttpEntity from Http Response Object
Log.v("Log1", "msg1");
HttpClient httpclient = new DefaultHttpClient();
HttpPost method = new HttpPost(url);
Log.v("Log1", "msg2");
HttpResponse response = httpclient.execute(method);
HttpEntity entity = response.getEntity();
if (entity != null) {
Log.v("Log2", "msg1");
} else {
Log.v("log2", "msg2");
}
return null;
}
protected void onPostExecute(final Void unused) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
}
}
Use this this in your activity class like this,
new xyz(ActivityClassName.this).execute();
There is a possibility of 2 issues here.
1- check if you have added proper network permissions to your AndroidManifest.xml file.
2- your code is executing a network request directly on main thread which Android does not allow. You have to execute this in worker thread e.g. use AsyncTask
It will be much better if you also put the log in your question.

Multiple Async Tasks for post in same activity

i wrote those threads:
How to manage multiple Async Tasks efficiently in Android
Running multiple AsyncTasks at the same time -- not possible?
but didnt find answer for my question, maybe someone can help..
I have android app which makes Login POST and getting json response,
if the Json is OK i need to POST another data to get another response.
i have extends Async Class which doing the post to the URL:
public class AsyncHttpPost extends AsyncTask<String, String, String> {
private HashMap<String, String> mData = null;
public AsyncHttpPost(HashMap<String, String> data) {
mData = data;
}
#Override
protected String doInBackground(String... params) {
byte[] result = null;
String str = "";
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(params[0]);// in this case, params[0] is URL
try {
ArrayList<NameValuePair> nameValuePair = new ArrayList<NameValuePair>();
Iterator<String> it = mData.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
nameValuePair.add(new BasicNameValuePair(key, mData.get(key)));
}
post.setEntity(new UrlEncodedFormEntity(nameValuePair, "UTF-8"));
HttpResponse response = client.execute(post);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpURLConnection.HTTP_OK){
result = EntityUtils.toByteArray(response.getEntity());
str = new String(result, "UTF-8");
}
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
catch (Exception e) {
return null;
}
return str;
}
#Override
protected void onPostExecute(String result) {
try {
JSONArray Loginjson = new JSONArray(result);
strStt = Loginjson.getJSONObject(0).getJSONObject("fields").getString("status");
if (strStt.equals("ERR")) {
ErrorMsg("Authentication failed");
} else if (strStt.equals("OK")) {
ErrorMsg("Login OK!!!");
ClientPage();
} else {
ErrorMsg("Connection Error");
}
} catch (JSONException e) {
ErrorMsg("Connection Error");
}
}
}
Now - i need to get another POST if the status is Error. do i need to make another Async class? with the same all procedures ? the issue is only the onPostExecute part is different.. actually the "doInBackground" will be always the same..
any idea how can i easily do multiple posts in the same activity?
Firstly, since your doInBackground() code will always stay the same, I recommend you move it into a general utility class.
Beyond that, you can go one of two ways:
Create a new AsyncTask for each type of request that can call your utility class, and have its own onPostExecute()
Create one AsyncTask that has a flag in it, which can be checked in the onPostExecute() method to see what code needs to be executed there. You will have to pass the flag in in the constructor or as a parameter in execute.
You can use a parameter at AsyncHttpPost constructor/execute or global variable to indicate if it is first or second POST (by other words - a flag). Then just create and execute another instance of AsyncHttpPost in onPostExecute (only if parameter/variable is set as "first POST").

onPostExecute never called?

public static class TestTask extends AsyncTask<Void, Integer, Integer> {
private String stacktrace;
public TestTask (String stacktrace){
this.stacktrace = stacktrace;
}
#Override
protected Integer doInBackground(Void... params) {
try {
Log.i("async", "doInBackground 1"); //this gets logged
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://xx.xx:8080/android/service.php");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("action", "logexception"));
nameValuePairs.add(new BasicNameValuePair("stacktrace", stacktrace));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
Log.i("async", "doInBackground 2"); //this gets logged
return 1;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
protected void onPreExecute(){
Log.i("async", "onPreExecute"); //this gets logged
}
#Override
protected void onPostExecute(Integer result) {
Log.i("async", "onPostExecute"); //this doenst get logged!
}
}
I've been checking out the other SO threads regarding this, but according to them, my code looks correct as far as i can tell. So why do i never reach Log.i("async", "onPostExecute");? Thanks
Did you create your AsyncTask on UI Thread?
Others seems good. Generics and annotations are fine.
So probably problem is that your doInBackground method never returns because onPostExecute is automatic called when doInBackground something will return.
You have to call the super in onPostExecute()
So you code should be like this:
#Override
public void onPostExecute(Integer result) {
super.onPostExecute(result);
Log.i("async", "onPostExecute");
}
And this should work

network + ui updates, asynctask vs handler

I have a map that i want to update from a separate thread. Im having some issues when i try to update the UI from my class that extends asynctask. And when i move the code to a handler in the main thread i get NetworkOnMainThreadException. Below is my asynctask. Is there any way to modify it to make it work?
#Override
protected Integer doInBackground(Void... params) {
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://83.xx.xx:8080/android/service.php");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("action", "getusers"));
nameValuePairs.add(new BasicNameValuePair("interval", Integer.toString(interval)));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
String jsonString = EntityUtils.toString(response.getEntity());
Gson gson = new GsonBuilder().create();
Type listType = new TypeToken<ArrayList<User>>() {}.getType();
ArrayList<User> userList = gson.fromJson(jsonString, listType);
((GoogleMapsActivity) activity).removeOverlayItems();
for(User user : userList ){
((GoogleMapsActivity) activity).addOverlayItem(Double.parseDouble(user.last_lat), Double.parseDouble(user.last_lng), user.bluetooth_name, "test desc");
}
return 1;
} catch (Exception e) {
e.printStackTrace();
}
return null;
Rather than touching the map in your doInBackground, return your data into onPostExecute. Then update the map from onPostExecute.
Please note that you should never retain a reference to your Activity from inside your AsyncTask or you could cause a memory leak.
Ideally, you should create an observer that can return data to your Activity.
interface Observer {
public void onMyDataAvailable(MyDataClass data);
}
Then, you instantiate your AsyncTask with a reference to this observer.
class MyAsyncTask extends AsyncTask ...
private Observer observer;
public MyAsyncTask(Observer observer) {
mObserver = observer;
}
public synchronized void onActivityDestroyed() {
mObserver = null;
}
public synchronized void onPostExecute(MyDataClass result) {
if (mObserver != null) {
mObserver.onMyDataAvailable(result);
}
}
Just make sure you call onActivityDestroyed() from your activity's onDestroy method. Otherwise your Activity will leak.

Categories

Resources