0

Android 2.3.3

I am integrating an AD service into one of my client's application.

Here is what I do in AsyncTask:

  1. Construct a query and use HTTP Get method to query the server with the desirable width and height along with other parameters.
  2. After getting the response from the server, I have to update it on the main thread (append the response as a HTML tag).

The problem is that the AD is getting displayed at random basis. Is this related to the network issue or is it related to my code? And also, if is using DefaultHTTPClient as good as anything else?

Code in main activity :

private static GetMMediaAdsTask mGetMMediaAds;

static String responseBody = "";

StringBuffer html = new StringBuffer();
....
....
html.append("<p>");
String url = "http://xxxx.com/getAd";

mGetMMediaAds = new GetMMediaAdsTask(context);
mGetMMediaAds.execute(url); // Calling the execute method of asynctask

...
...
...
html.append(responseBody);
html.append("</p>");

AsyncTask SubClass

public static class GetMMediaAdsTask extends AsyncTask<String, Void, Boolean>{

    String url = "http://ads.mp.mydas.mobi/getAd";
    String apid = "123xxx";
    String auid = "";

    String returned = "";

    private Context mContext;


    public GetMMediaAdsTask(Context context) {
        // TODO Auto-generated constructor stub
        mContext = context;
    }


    @Override
    protected Boolean doInBackground(String... params) {
        // TODO Auto-generated method stub

        System.out.println("***** Inside AsyncTask *****");

        auid = Secure.getString(mContext.getContentResolver(), Secure.ANDROID_ID);

        int hsht = 0;
        int hswd = 0;

        DisplayMetrics metrics = new DisplayMetrics();
        ((Activity) mContext).getWindowManager().getDefaultDisplay().getMetrics(metrics);

        int height = metrics.heightPixels;
        int width = metrics.widthPixels;

        System.out.println("Height ="+height+" Width = "+width);

        if(width <= 320)
        {
            hswd = 320;
            hsht = 53;
        }
        else if(width > 320 && width < 468)
        {
            hswd = 320;
            hsht = 53;
        }
        else if(width >= 468 && width < 728)
        {
            hswd = 468;
            hsht = 60;
        }
        else if(width >= 728)
        {
            hswd = 728;
            hsht = 90;
        }

        String query = String.format("apid=%s&auid=%s&hsht=%d&hswd=%d", apid, auid, hsht, hswd);
        System.out.println("query = "+query);

        try {
            DefaultHttpClient http = new DefaultHttpClient();
            HttpGet httpMethod = new HttpGet();
            httpMethod.setURI(new URI(url + "?" + query));
            HttpResponse response = http.execute(httpMethod);
            int responseCode = response.getStatusLine().getStatusCode();
            switch (responseCode) {
            case 200:
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    returned = EntityUtils.toString(entity);
                    System.out.println("response = "+returned);

                }
                break;
            }

        } catch (Exception e) {
            System.out.println("Exception occured");
        }



        return true;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        // TODO Auto-generated method stub

        System.out.println("***** Inside PostExecute *****");
        responseBody = returned;

        super.onPostExecute(result);
    }

}
Vamsi Challa
  • 11,038
  • 31
  • 99
  • 149
  • In onPostExecute you set `responseBody = returned` but you also have to let the Activity know when the execution of the task is done. That is call a method of your Activity and pass it the response body and assemble your html page inside this method. – devconsole May 27 '13 at 12:16
  • The problem is, the html is being constructed using the stringbuffer and at the bottom (just before appending the

    tag) I have to append this response from the server.

    – Vamsi Challa May 27 '13 at 12:36
  • And since I am starting a thread(asynctask), even before i get the response, the html construction is done. – Vamsi Challa May 27 '13 at 12:37
  • Probably i should start the asynctask, sometime before, so that the parallel execution can take place and i get the response before the ending html tag is reached. – Vamsi Challa May 27 '13 at 12:38
  • You don't know in advance how long the network call will take, that is the point of the whole asynchronous execution. Take that block of code starting with `StringBuffer html = new StringBuffer();` up to `html.append("");` and put it in a method. Then execute that method as soon as you have the response from the server. – devconsole May 27 '13 at 12:45
  • Ok.. I will give it a try... – Vamsi Challa May 27 '13 at 12:55

1 Answers1

0

AsyncTask and UI thread are executed in parallel, so by the time you do html.append(responseBody); responseBody may not be set yet.

Move code that updates UI based on the AsyncTask result to onPostExecute - it is guaranteed to be called on the UI thread after doInBackground is completed

And instead of the static returned, it is better to make it AsyncTask result

msh
  • 2,700
  • 1
  • 17
  • 23