0

I am new to Stackoverflow.

I am trying to make a Unit Converter in which the function "calculateCurrency" returns a Double value of the result. But the value of TextView "outputNumber" is always changing based on the previous input.

Ex- If I type 1, then the outputNumber is changed to "null" but when I enter another digit after 1, then the outputNumber changes to the value it was supposed to be changed on 1. But the Toast is displaying the correct value i.e. on 1, it is displaying 1 so the value of myInputNumber is correct according to the input.

Can anyone help me?

inputNumber.addTextChangedListener(
            new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                }

                @Override
                public void afterTextChanged(Editable s) {
                    try {
                        myInputNumber = Double.parseDouble(s.toString());
                        Double myText = calculations.calculateCurrency(myInputNumber, convertFrom, convertTo);
                        Toast.makeText(MainActivity.this, myInputNumber+"", Toast.LENGTH_SHORT).show();
                        outputNumber.setText(myText+"");
                    } catch (ExecutionException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }
    );

The code of calculations.calculateCurrency is:

 public Double calculateCurrency(Double input, String convertFrom, String convertTo) throws ExecutionException, InterruptedException {
        myCurrencyFetcher fetchCurrency = new myCurrencyFetcher();
        fetchCurrency.execute(Double.toString(input), convertFrom, convertTo);
        return myText;
}


class myCurrencyFetcher extends AsyncTask<String, Double, Double>{

    URL url;
    StringBuffer stringBuffer;

    @Override
    protected Double doInBackground(String... params) {
        try{
            Double myInputNumber = Double.parseDouble(params[0]);
            String convertFrom = params[1];
            String convertTo = params[2];
            url = new URL("http://api.fixer.io/latest?base="+convertFrom+"&symbols="+convertTo);

            HttpURLConnection connection;
                connection = (HttpURLConnection) url.openConnection();
                connection.connect();

                InputStream inputStream = connection.getInputStream();

                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

                stringBuffer = new StringBuffer();

                String line = "";
                while((line = reader.readLine()) != null){
                    stringBuffer.append(line);
                }
            String finalJSON = stringBuffer.toString();

            JSONObject parentObject = new JSONObject(finalJSON);
            JSONObject finalObject = parentObject.getJSONObject("rates");

            String rate = finalObject.getString(convertTo);
            //String year = finalObject.getString("year");
            Double myRate = Double.parseDouble(rate);

            return myInputNumber*myRate;
            } catch (Exception e) {
                e.printStackTrace();
            }
        return null;
    }

    @Override
    protected void onPostExecute(Double result) {
        super.onPostExecute(result);
        Calculations.myText = result;
    }
}
Akarsh
  • 1
  • 4
  • 1
    network call will take time so values of ` Calculations.myText` will not be updated instantly , apply callbacks through interface – Pavneet_Singh May 28 '17 at 16:23
  • This is a link about how to use callback in AsyncTask, https://stackoverflow.com/a/28513523/7973751 – Sunhee May 28 '17 at 17:08

2 Answers2

0

Try again add synchronized at method calculations.calculateCurrency(myInputNumber, convertFrom, convertTo);

Dungnbhut
  • 176
  • 5
0

You have to change your code.

@Override
    public void afterTextChanged(Editable s) {
        try {
            myInputNumber = Double.parseDouble(s.toString());
            Double myText = calculations.calculateCurrency(myInputNumber, convertFrom, convertTo);
            Toast.makeText(MainActivity.this, myInputNumber+"", Toast.LENGTH_SHORT).show();
            //outputNumber.setText(myText+""); // Remove this line
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (Exception e){
            e.printStackTrace();
        }
    }

Add TextView (outputNumber) to Constructor as argument. myCurrencyFetcher fetchCurrency = new myCurrencyFetcher(outputNumber);

class myCurrencyFetcher extends AsyncTask<String, Double, Double>{

 private WeakReference<TextView> weakOutputNumber; 

 public myCurrencyFetcher (TextView outputNumber) {
     weakOutputNumber= new WeakReference<TextView>(outputNumber);
 } 

 /* ... Other methods are the same */

 @Override
    protected void onPostExecute(Double result) {
        super.onPostExecute(result);
        //Calculations.myText = result;
        if (weakOutputNumber != null) {
        TextView outputNumber = weakOutputNumber.get();
           if (outputNumber != null) {
               outputNumber.setText(new String(result));
           }
        }

    }

}
Sunhee
  • 101
  • 8
  • I can't access outputNumber in my Calculations class in which the Asynctask class is used because my TextView outputNumber is in MainActivity. – Akarsh May 28 '17 at 16:27
  • I posted. please check it. – Sunhee May 28 '17 at 16:36
  • As I mention above, add TextView (outputNumber) to Constructor as argument like myCurrencyFetcher fetchCurrency = new myCurrencyFetcher(outputNumber); – Sunhee May 28 '17 at 16:46
  • `myCurrencyFetcher fetchCurrency = new myCurrencyFetcher();`
    Now it is saying `myCurrencyFetcher(TextView) cannot be applied to ()`
    – Akarsh May 28 '17 at 16:47
  • Did you change **myCurrencyFetcher fetchCurrency = new myCurrencyFetcher();** to **myCurrencyFetcher fetchCurrency = new myCurrencyFetcher(outputNumber)** ? – Sunhee May 28 '17 at 16:50
  • Yes. Still not working. It is showing `cannot resolve symbol outputNumber` in `myCurrencyFetcher fetchCurrency = new myCurrencyFetcher(outputNumber)` – Akarsh May 28 '17 at 16:55
  • Where did you declare outputNumber variable and define calculateCurrency method? – Sunhee May 28 '17 at 16:57
  • The variable outputNumber is in MainActivity.java while the calculateCurrency is in Calculations.java – Akarsh May 28 '17 at 17:00
  • So... Please add one argument TextView outputNumber to **calculateCurrency(Double input, String convertFrom, String convertTo)** like calculateCurrency(TextView outputNumber, Double input, String convertFrom, String convertTo) – Sunhee May 28 '17 at 17:02
  • Cool~! Good luck~ – Sunhee May 28 '17 at 17:09