0

i'm not sure this is the perfect title for this but its the best i could come up with.

I have a java class ApiRequest the runs some http requests and returns the result in a callback via an interface. Example will be the authenticate method below:

public class ApiRequest {

     private Context context;
     private ApiRequestCallback api_request_callback;

    public ApiRequest ( Context context ){
       this.context = context;

       // this can either be activity or context. Neither works in fragment
       // but does in activity
       this.api_request_callback = ( ApiRequestCallback ) context;
    }

 public interface ApiRequestCallback {
    void onResponse(JSONObject response );
    void onErrorResponse(JSONObject response );
}

public JsonObject authenticate(){
   .... do stuff and when you get response from the server. This is some 
   kinda of async task usually takes a while

   // after you get the response from the server send it to the callback
   api_request_callback.onResponse( response );
}

Now i have a fragment class in a tablayout, that implements this class below

public class Home extends Fragment implements ApiRequest.ApiRequestCallback 
{

  // I have tried
  @Override
   public void onViewCreated(.........) {
      api_request = new ApiRequest( getContext() );
   }


   // and this two
   @Override
   public void onAttach(Context context) {
      super.onAttach(context);
      api_request = new ApiRequest( context );
   }

   @Override
public void onResponse(JSONObject response) {
   //I expect a response here
}

}

The response i get is that i can cannot cast: the activity context to the interface.

Java.lang.ClassCastException: com.*****.**** cannot be cast to com.*****.****ApiRequest$ApiRequestCallback

But this works with a regular activity so its really has me on the edge. A fix for this will be greatly appreciated. A teachable moment for me i'd say. Thanks

Mueyiwa Moses Ikomi
  • 1,069
  • 2
  • 12
  • 26

1 Answers1

1

To construct your ApiRequest object, you are passing context. In the constructor, you are assuming that you can always cast this context to ApiRequestCallback (this is the error you are doing). Like in your fragment - fragment does not have a context of its own, when you use getContext() in a fragment, it returns the parent activity's context and this in your ApiRequest class's constructor can't be cast to ApiRequestCallback.

Change ApiRequest constructor to below :

public ApiRequest (Context context, ApiRequestCallback api_request_callback){
       this.context = context;
       this.api_request_callback = api_request_callback;
}

and then in your fragment use this :

api_request = new ApiRequest(getContext(), Home .this);
Nikhil Gupta
  • 881
  • 6
  • 14
  • thanks but why am i passing apiRequestCallbask as a parameter in ApiRequest? – Mueyiwa Moses Ikomi Apr 15 '18 at 13:32
  • because you need it to initialise api_request_callback in your ApiRequest class. It works for an activity because it has its own context. But for all other things like an adapter or a fragment in your case they don't have an context of their own. So context and ApiRequestCallback interface can't be same object. So you need to send to parameters. – Nikhil Gupta Apr 15 '18 at 13:34