0

I'm trying to make a currency converter with an api for my school project. The converter is coded into a Fragment. Everytime I try to convert a pair by pressing the Button, the app crashed. This is the error I get:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.LulusApp, PID: 1675
    java.lang.NoSuchMethodError: No static method metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; in class Ljava/lang/invoke/LambdaMetafactory; or its super classes (declaration of 'java.lang.invoke.LambdaMetafactory' appears in /apex/com.android.art/javalib/core-oj.jar)
        at okhttp3.internal.Util.<clinit>(Util.java:87)
        at okhttp3.internal.Util.skipLeadingAsciiWhitespace(Util.java:321)
        at okhttp3.HttpUrl$Builder.parse(HttpUrl.java:1313)
        at okhttp3.HttpUrl.get(HttpUrl.java:917)
        at retrofit2.Retrofit$Builder.baseUrl(Retrofit.java:492)
        at com.example.LulusApp.Retrofit.RetrofitBuilder.getRetrofitInstance(RetrofitBuilder.java:11)
        at com.example.LulusApp.CurrencyConverterFragment$1.onClick(CurrencyConverterFragment.java:53)
        at android.view.View.performClick(View.java:7448)
        at android.view.View.performClickInternal(View.java:7425)
        at android.view.View.access$3600(View.java:810)
        at android.view.View$PerformClick.run(View.java:28305)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
I/Process: Sending signal. PID: 1675 SIG: 9

This is my CurrencyConverterFragment.java where everything is connected:

public class CurrencyConverterFragment extends Fragment {


    public CurrencyConverterFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_currency_converter, container, false);

        final EditText currencyAmount = (EditText) view.findViewById(R.id.currency_amount);
        final EditText currencyResult = (EditText) view.findViewById(R.id.currency_result);
        final Spinner currencyFromDropdown = (Spinner) view.findViewById(R.id.currency_from);
        final Spinner currencyToDropdown = (Spinner) view.findViewById(R.id.currency_to);
        Button buttonResult = (Button) view.findViewById(R.id.button_result);

        //Adding Functionality
        String[] dropDownList = {"USD", "EUR","CHF"};
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(),R.layout.support_simple_spinner_dropdown_item,dropDownList);
        currencyFromDropdown.setAdapter(adapter);
        currencyToDropdown.setAdapter(adapter);

        buttonResult.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//Below is error line 53
                RetrofitInterface retrofitInterface = RetrofitBuilder.getRetrofitInstance().create(RetrofitInterface.class);
                Call<JsonObject> call = retrofitInterface.getExchangeCurrency(currencyFromDropdown.getSelectedItem().toString());
                call.enqueue(new Callback<JsonObject>() {
                    @Override
                    public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
                        Log.d("response",String.valueOf(response.body()));
                        JsonObject res = response.body();
                        JsonObject conversion_rates = res.getAsJsonObject("conversion_rates");
                        double amount = Double.parseDouble(currencyAmount.getText().toString());
                        double multiplier = Double.parseDouble(conversion_rates.get(currencyToDropdown.getSelectedItem().toString()).toString());
                        double result = amount * multiplier;
                        currencyResult.setText(String.valueOf(result));
                    }

                    @Override
                    public void onFailure(Call<JsonObject> call, Throwable t) {

                    }
                });
            }
        });




        return view;
    }
}

Here is the .xml layout file with the 2 Spinner, 2 EditText, Some TextView and the Button:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".CurrencyConverterFragment">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:id="@+id/Converter_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Currency Converter"
            android:textSize="36dp"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium"
            android:textColor="?attr/colorPrimary"
            android:layout_margin="20dp"
            android:layout_gravity="center"/>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_gravity="center">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Amount to be converted"
            android:textSize="16dp"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium"
            android:textColor="?attr/colorPrimary"
            android:layout_margin="20dp"/>

        <EditText
            android:id="@+id/currency_amount"
            android:layout_width="250dp"
            android:layout_height="40dp"
            android:layout_gravity="center"
            android:textColor="?attr/colorPrimary"
            android:layout_marginBottom="20dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="From Currency:"
            android:textSize="16dp"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium"
            android:textColor="?attr/colorPrimary"
            android:layout_margin="20dp"/>

            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/border_spinner_currency_converter"
                android:layout_marginBottom="20dp"
                android:layout_marginLeft="20dp"
                android:layout_marginRight="20dp">
                <Spinner
                    android:layout_width="250dp"
                    android:layout_height="40dp"
                    android:id="@+id/currency_from"
                    android:layout_gravity="center"/>
            </RelativeLayout>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="To Currency:"
            android:textSize="16dp"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium"
            android:textColor="?attr/colorPrimary"
            android:layout_margin="20dp"/>

            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/border_spinner_currency_converter"
                android:layout_marginBottom="20dp"
                android:layout_marginLeft="20dp"
                android:layout_marginRight="20dp">
                <Spinner
                    android:layout_width="250dp"
                    android:layout_height="40dp"
                    android:id="@+id/currency_to"
                    android:layout_gravity="center"/>
            </RelativeLayout>
        </LinearLayout>
        <Button
            android:id="@+id/button_result"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="20dp"
            android:layout_gravity="center"
            android:text="Convert"
            android:textColor="#FFFFFF"
            android:background="@drawable/custom_button_currency_converter"/>

        <EditText
            android:id="@+id/currency_result"
            android:layout_width="250dp"
            android:layout_height="40dp"
            android:layout_gravity="center"
            android:layout_marginBottom="20dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:hint="Result"/>

    </LinearLayout>
</ScrollView>

My RetrofitBuilder.java for the api I use:

public class RetrofitBuilder {
    private static Retrofit retrofit;
    public static Retrofit getRetrofitInstance(){
        if(retrofit == null){
            retrofit = new Retrofit.Builder()
//Below is error line 11:
                    .baseUrl("https://v6.exchangerate-api.com/v6/9b7aaded7a6b901a07526894/")
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

Finally the interface to @GET a specific currency by it's @Path.

public interface RetrofitInterface {
    @GET("latest/{currency}")
    Call<JsonObject> getExchangeCurrency(@Path("currency")String currency);
}
  • 1
    Which is the actual error you get? and which is line 53 ?? – Mr R Mar 14 '21 at 13:21
  • After your "get" calls, check that you actually got something. – stark Mar 14 '21 at 13:26
  • The error log trace is incomplete, no one would be able to deduce anything out of it. Please post the entire log. – iCantC Mar 14 '21 at 13:56
  • @MrR I marked it with comments in the code, sorry. I missed that. Hope it helps to find it out. –  Mar 14 '21 at 14:39
  • @iCantC I edited the error with the entire log. Thank you for your help! –  Mar 14 '21 at 14:39
  • @Lulu96 have you checked out this https://stackoverflow.com/questions/59448845/no-static-method-metafactory/59448917 ? – iCantC Mar 14 '21 at 14:43
  • @iCantC That didn't worked. Other idea? –  Mar 14 '21 at 15:19
  • @Lulu96 have tried all three answers on that link ? At least one should've worked – iCantC Mar 14 '21 at 15:31
  • @iCantC Answer 1 and 3 is the same. And the 2nd one didn't work also. –  Mar 14 '21 at 15:51
  • It definitely seems like you don't have the right library at runtime (which is what @iCantC is saying). – Mr R Mar 14 '21 at 20:57

1 Answers1

0

Retrofit class is not & can't be static. If a class is static, is cannot contain any members that are non-static. That is why the runtime error states there is no such static method. Get Retrofit instance in the onCreate method, or make a constructor method for RetrofitBuilder class with the Context as parameter. Then build interface and perform .create(RetrofitInterface.class); there, not outside. Add a get() method in the class as well, for retrieving the Retrofit instance, and call the class like new RetrofitBuilder(getApplicationContext()) from outside when you require it.

mindoverflow
  • 730
  • 4
  • 13
  • I wish I could do that. Can you implement your solution into my code? Like the snippets I need to add. I'm really new to this. Thank you honey! –  Mar 14 '21 at 16:47