0

My class reads a json string from web and with collected string populate an hashmap. I'm using AsyncTask to read data with a progressdialog to let the user that the devise "is working". This is my class:

class ArmoryAsyncProgress extends AsyncTask<String, Void, Void> {

    private Context         mContext;
    private ProgressDialog  mProgressDialog;
    private String tempRes;

    public ArmoryAsyncProgress(Context mContext)
    {
        this.mContext = mContext;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mProgressDialog = ProgressDialog.show(mContext, "Carica!", "Gira!");
    }

    @SuppressLint("NewApi")
    @Override
    protected String doInBackground(String... sUrl) {
        try {
            URL json = new URL(Utility.BASE_URL + "api.php?action=armory&guid="+pGuid);
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(
                            json.openStream()));
            String input;
            while((input = in.readLine()) != null)
                Result += input;

            json = new URL(Utility.BASE_URL + "api.php?action=armory_stats&guid="+pGuid);
            in = new BufferedReader(
                    new InputStreamReader(
                            json.openStream()));
            input = "";
            String ret = "";
            while((input = in.readLine()) != null)
                ret += input;

            tempRes = Result + "Ø" + ret;
            String debug = tempRes;
        }
        catch(MalformedURLException e){
            e.printStackTrace();
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }

        ActivityArmory.result = tempRes;
        return null;
    }

    protected void onPostExecute(String result) {

        /*********************************************************************************/
        try
        {
            String ret;
            while(result == null)
                Thread.sleep(500);
            String[] temp = result.split("Ø");
            pJSON = temp[0];
            ret = temp[1];

            JSONObject pl = new JSONObject(ret);
            stats.put("Level", pl.getString("level"));
            stats.put("Classe", pl.getString("class"));
            stats.put("Name", pl.getString("pname"));
            stats.put("Race", pl.getString("race"));

            stats.put("health", pl.getString("health"));
            stats.put("power", pl.getString("power1"));
            stats.put("gname", pl.getString("gname"));
            stats.put("pnote", pl.getString("pnote"));
            stats.put("offnote", pl.getString("offnote"));
            stats.put("rname", pl.getString("rname"));

            JSONArray jObject = new JSONArray(pJSON);

            for (int i = 0; i < jObject.length(); i++) {
                JSONObject item = jObject.getJSONObject(i);
                ArmoryElement i1 = new ArmoryElement(
                        "http://wow.zamimg.com/images/wow/icons/large/" + item.getString("itemIMG") + ".jpg",
                        item.getInt("itemID"), item.getInt("quality"));

                el.put(item.getString("itemType"), i1);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    /****************************************************************/

        mProgressDialog.dismiss();
    }
}

and this is the call to the class:

new ArmoryAsyncProgress().execute(pGuid+"");

After the "execute" method call i call another function, used to format and display data fetched from web. My problem is that the progressDialog declared in the Async class is not showed and the function called after execute gets called before the execution is finished (Using some Log i found that the log in the second function are displayed before the doInBackground finish)

I tried the .get mothod too, it freezes the main thread and prevent the function from being called, but i can't show the progressdialog.

Thanks in advance

Mattiag
  • 108
  • 2
  • 10
  • its normal that the async task works async. you only can be sure that the async task is terminated when he enters onPostExecute. – MemLeak Mar 06 '14 at 14:42
  • and what can I do to prevent the code from being executed? – Mattiag Mar 06 '14 at 14:44
  • I posted the real problem, you should pass the allready parsed object and only do the gui stuff. but check my answer, the problem is your returning null. – MemLeak Mar 06 '14 at 14:49

4 Answers4

1

the function called after execute gets called before the execution is finished

This is normal since AsyncTasks are asynchronous, meaning they will run in the background and allow your other code to keep going. To fix this,

  1. If the task is an inner class of the Activity, you can call the function you want to run after it finishes in onPostExecute()

  2. If it is not then you can use an interface to provide a callback to the Activity once it has finished. See this answer for an example on interface

Why the ProgressDialog isn't showing, I'm not quite sure but you could start by removing Thread.sleep() from onPostExecute() as that will make your main thread sleep. The only thing I see that needs to be in onPostExecute() is mProgressDialog.dismiss(). The rest could be done in doInBackground().

Also, you are right about using .get(), it will freeze your UI Thread.

Community
  • 1
  • 1
codeMagic
  • 44,549
  • 13
  • 77
  • 93
1

PostExecute() must not perform large operation, use those heavy operation like json parsing in doInBackground. To display UI ie to display in textview or in listview use PostExecute()

andrewsi
  • 10,807
  • 132
  • 35
  • 51
Shadow
  • 6,864
  • 6
  • 44
  • 93
0

The bad part is:

    protected void onPostExecute(String result) {

    /*********************************************************************************/
    try
    {
        String ret;
        while(result == null)
            Thread.sleep(500);

Because this runs in UI thread and will conflict with the strict mode.

    protected void onPostExecute(String result) {
if(result!=null){
    /*********************************************************************************/
    try
    {
        String ret;

        String[] temp = result.split("Ø");
        pJSON = temp[0];
        ret = temp[1];

        JSONObject pl = new JSONObject(ret);
        stats.put("Level", pl.getString("level"));
        stats.put("Classe", pl.getString("class"));
        stats.put("Name", pl.getString("pname"));
        stats.put("Race", pl.getString("race"));

        stats.put("health", pl.getString("health"));
        stats.put("power", pl.getString("power1"));
        stats.put("gname", pl.getString("gname"));
        stats.put("pnote", pl.getString("pnote"));
        stats.put("offnote", pl.getString("offnote"));
        stats.put("rname", pl.getString("rname"));

        JSONArray jObject = new JSONArray(pJSON);

        for (int i = 0; i < jObject.length(); i++) {
            JSONObject item = jObject.getJSONObject(i);
            ArmoryElement i1 = new ArmoryElement(
                    "http://wow.zamimg.com/images/wow/icons/large/" + item.getString("itemIMG") + ".jpg",
                    item.getInt("itemID"), item.getInt("quality"));

            el.put(item.getString("itemType"), i1);
        }
    } catch (JSONException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
/****************************************************************/
}
    mProgressDialog.dismiss();
}

the even bader part is:

 return null;

in your doInBackground method

However, this should work:

class ArmoryAsyncProgress extends AsyncTask<String, Void, Void> {

    private Context         mContext;
    private ProgressDialog  mProgressDialog;
    private String tempRes;

    public ArmoryAsyncProgress(Context mContext)
    {
        this.mContext = mContext;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mProgressDialog = ProgressDialog.show(mContext, "Carica!", "Gira!");
    }

    @SuppressLint("NewApi")
    @Override
    protected String doInBackground(String... sUrl) {
        try {
            URL json = new URL(Utility.BASE_URL + "api.php?action=armory&guid="+pGuid);
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(
                            json.openStream()));
            String input;
            while((input = in.readLine()) != null){
                Result += input;
            }
            json = new URL(Utility.BASE_URL + "api.php?action=armory_stats&guid="+pGuid);
            in = new BufferedReader(
                    new InputStreamReader(
                            json.openStream()));
            input = "";
            String ret = "";
            while((input = in.readLine()) != null){
                ret += input;
            }
            tempRes = Result + "Ø" + ret;
            String debug = tempRes;
        }
        catch(MalformedURLException e){
            e.printStackTrace();
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }

        ActivityArmory.result = tempRes;
        return tempRes;
    }

    protected void onPostExecute(String result) {
        if(result!=null)
        /*********************************************************************************/
        try
        {
            String ret;
            String[] temp = result.split("Ø");
            pJSON = temp[0];
            ret = temp[1];

            JSONObject pl = new JSONObject(ret);
            stats.put("Level", pl.getString("level"));
            stats.put("Classe", pl.getString("class"));
            stats.put("Name", pl.getString("pname"));
            stats.put("Race", pl.getString("race"));

            stats.put("health", pl.getString("health"));
            stats.put("power", pl.getString("power1"));
            stats.put("gname", pl.getString("gname"));
            stats.put("pnote", pl.getString("pnote"));
            stats.put("offnote", pl.getString("offnote"));
            stats.put("rname", pl.getString("rname"));

            JSONArray jObject = new JSONArray(pJSON);

            for (int i = 0; i < jObject.length(); i++) {
                JSONObject item = jObject.getJSONObject(i);
                ArmoryElement i1 = new ArmoryElement(
                        "http://wow.zamimg.com/images/wow/icons/large/" + item.getString("itemIMG") + ".jpg",
                        item.getInt("itemID"), item.getInt("quality"));

                el.put(item.getString("itemType"), i1);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    /****************************************************************/
    }
        mProgressDialog.dismiss();
    }
}
MemLeak
  • 4,456
  • 4
  • 45
  • 84
0

you must change the return value of doInBackground because this value is used in onPostExecute

user2689294
  • 129
  • 7