I'm trying to update this RetroFit + Otto tutorial, so my code updated is:
IWeather.java
RetroFit 2.+ doesn't allow to return void
, so instead of void getWeather(...)
I added Call<Weather> getWeather(...)
.
public interface IWeather {
@GET("/{latitude},{longitude}")
Call<Weather> getWeather(@Path("latitude") String latitude,
@Path("longitude") String longitude,
Callback<Weather> callback);
}
ForecastClient.java
RetroFit 2.+ has changed his constructor, so the new ForecastClient
has the next form. The IllegalArgumentException
points to the weather.getWeather(...)
method.
public class ForecastClient {
private static final String BASE_URL = "https://api.darksky.net/forecast/";
private static final String API_KEY = "******************";
public static final String API_URL = BASE_URL + API_KEY + "/";
private static ForecastClient mForecastClient;
private static Retrofit mRetroAdapter;
public static ForecastClient getClient() {
if (mForecastClient == null) {
mForecastClient = new ForecastClient();
}
return mForecastClient;
}
private ForecastClient() {
mRetroAdapter = new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(new OkHttpClient())
.build();
}
public void getWeather(String latitude, String longitude, Callback<Weather> callback) {
IWeather weather = mRetroAdapter.create(IWeather.class);
weather.getWeather(latitude, longitude, callback);
}
}
ForecastManager.java
public class ForecastManager {
private Context mContext;
private Bus mBus;
private ForecastClient sForecastClient;
public ForecastManager(Context context, Bus bus) {
this.mContext = context;
this.mBus = bus;
sForecastClient = ForecastClient.getClient();
}
@Subscribe
public void onGetWeatherEvent(GetWeatherEvent getWeatherEvent) {
String latitude = Double.toString(getWeatherEvent.getLatitude()).trim();
String longitude = Double.toString(getWeatherEvent.getLongitude()).trim();
Callback<Weather> callback = new Callback<Weather>() {
@Override
public void onResponse(Call<Weather> call, Response<Weather> response) {
Log.d(ForecastManager.class.getSimpleName(), response.body().toString());
mBus.post(new SendWeatherEvent(response.body()));
}
@Override
public void onFailure(Call<Weather> call, Throwable t) {
Log.e(ForecastManager.class.getSimpleName(), t.getMessage());
}
};
sForecastClient.getWeather(latitude, longitude, callback);
}
}
I'm receiving a No Retrofit annotation found and I guess the reason is something related with my callback, but it is a RetroFit callback, so I don't understand why the error.
The stacktrace points to the MainActivity, in particular to the Otto's method post()
with a java.lang.RuntimeException: Could not dispatch event
, caused by the error previously mentioned java.lang.IllegalArgumentException: No Retrofit annotation found. (parameter #3)
:
MainActivity.java
public class MainActivity extends AppCompatActivity {
@BindView(R.id.activity_main_textView)
TextView textView;
@BindView(R.id.activity_main_button)
Button button;
private static final double LATITUDE = **.******;
private static final double LONGITUDE = **.******;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
}
@OnClick(R.id.activity_main_button)
public void onClick(View view) {
BusProvider.getInstace().post(new GetWeatherEvent(LATITUDE, LONGITUDE));
}
@Subscribe
public void onSendWeatherEvent(SendWeatherEvent sendWeatherEvent) {
Weather weather = sendWeatherEvent.getWeather();
Currently currently = weather.getCurrently();
textView.setText(currently.getSummary());
}
Any clue about where is the error or how should I handle the bus subscriptions, the callback, etcetera?
java.lang.IllegalArgumentException: No Retrofit annotation found. (parameter #3)
As the error says, the problem is that the third parameter of the getWeather
method does not have an annotation. The Callback
class is used for the Call#enqueue(Callback)
method.
Simply change sForecastClient.getWeather(latitude, longitude, callback)
to sForecastClient.getWeather(latitude, longitude).enqueue(callback)
and remove the third parameter.
Try it and modify your retrofit version number to 2.6.0。The use of coroutines in Retrofit 2.6.0 can return a Response object directly. If await() is not needed, Retrofit will automatically call it. This is not applicable when the version is below 2.6.0.
来源:https://stackoverflow.com/questions/44966286/java-lang-runtimeexception-no-retrofit-annotation-found-parameter-3