Question

In some way I do understand the Handler, but I'm not sure what to do with the params and how to let the code wait until the job is done in the background. I want the UI to be normally working and in the background I want to do an exchange rate calculation.

I have the following:

I call new getOnlineExchangeRate().execute(""); //Get Exchange Rate in BG

After that I want to have a result=amount*exchangerate, but the code is not waiting for the result. Can somebody tell me how the calculation waits till we have an exchangerate. Do I have to send some params and how would that look?

.
.
.
.
.
public double getYahooExchangeRate(String ER){

        double exchangerate=0;

    try {

        s = getJson("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22"+ER+"%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");                       
        //s = getJson("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22"+val[from]+val[to]+"%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");                      

        JSONObject jObj;
        jObj = new JSONObject(s);
        String exResult = jObj.getJSONObject("query").getJSONObject("results").getJSONObject("rate").getString("Rate");

        exchangerate=Double.parseDouble(exResult);

        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            ALS.Toast(myContext.getString(R.string.conversionerror), false);
        }
        catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            ALS.Toast(myContext.getString(R.string.conversionerror), false);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            ALS.Toast(myContext.getString(R.string.conversionerror), false);
        }                                   
    return exchangerate;

}       



public String getJson(String url)throws ClientProtocolException, IOException {

StringBuilder build = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String con;
while ((con = reader.readLine()) != null) {
    build.append(con);
}
return build.toString();
}



public class getOnlineExchangeRate extends AsyncTask<String, Void, String> {


      @Override

      protected void onPostExecute(String result) {

        // execution of result of Long time consuming operation
          ALS.Toast(myContext.getString(R.string.exchangeratesupdated), true);


      }


    @Override
    protected String doInBackground(String... params) {
        // TODO Auto-generated method stub
         // perform long running operation operation

         getYahooExchangeRate(USDEUR);
        return null;
    }
Was it helpful?

Solution

I think your problem is in this line:

@Override
protected String doInBackground(String... params) {
    getYahooExchangeRate(USDEUR);
    return null;

You want to return the result of getYahooExchangeRate and not null :) So change this and the return-value should be a double. So change this to:

@Override
protected Double doInBackground(String... params){
    return getYahooExchangeRate(USDEUR);
}

You also have to change your class header:

public class getOnlineExchangeRate extends AsyncTask<String, Void, Double> {


AsyncTask<Params, Progress, Result>

The generic part tells the AsyncTask which Informationstypes are handled. The first is the type for the params of doInBackground(Params... ) The second is the type of the progress-Information The last explains which type is returned by doInBackground(), so it changes the method-header from

protected Result doInBackground(Params... params){ };

to protected double doInBackground(Params... params){};

To bring back the Result i would use and Observer oder Callback-Pattern.

Edit: changed double to Double, because primitives cannot be used for Generics.

OTHER TIPS

the code is not waiting for the result. Can somebody tell me how the calculation waits till we have an exchangerate. Do I have to send some params and how would that look?

You could use AsyncTask#get() to force the code to wait, but this blocks the main thread until the AsyncTask completes which defies the purpose of using an asynchronous task.

It is best to design your Activity to proceed without the exchange rate, just like my mail app loads allowing me to compose messages and read old messages while the new messages are being fetched. When the asynchronous data loads then you can update your UI with the new information. (I believe this is what you are trying to do.)


To add on to user1885518 code, you should use your AsyncTask as a subclass in your Activity like this:

public class MainActivity extends Activity {
    private class getOnlineExchangeRate extends AsyncTask<Void, Void, Double> {
        @Override
        protected Double doInBackground(Void... params) {
            return getYahooExchangeRate(params[0]);
        }

        @Override
        protected void onPostExecute(Double rate) {
            // Do something with rate
        }       
    }

    ...
}

Once you know which exchange rate you want, call:

new getOnlineExchangeRate().execute(USDEUR); //Get Exchange Rate in BG

Now when you have gotten the rate from online, the code calls onPostExecute() with your desired rate. Inside on onPostExceute() you can call whatever method you want in your ACtivity to calculate result=amount*exchangerate and display result wherever it is appropriate.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top