codeKiller
codeKiller

Reputation: 5739

ClassException casting Interface

I have a fragment, which is being used inside a MainActivity, actually it is used inside a ViewPager in a MainActivity.

public class Myfragment extends Fragment implements MySingleton.ResponseInterface{


    public static Myfragment newInstance() {
        final Myfragment mf = new Myfragment();
        return mf;
    }

    public Myfragment() {
    }

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        //.....
        final MySingleton mysingleton = MySingleton.getInstance(getContext());

        //I have a button in the fragment that I use like this

        myButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            mysingleton.getSomeResponse();
        }
    });

}

@Override
    public void onResponseGiven(String response) {
        Log.d("response", response);
    }

}

I have a Singleton class to be used for different actions, the singleton includes an interface:

public class MySingleton{


    private static MySingleton mInstance;
    private static Context mContext;
    public ResponseInterface responseInterface;

    private MySingleton(Context context){
        mContext = context;
        this.responseInterface = (ResponseInterface) context;

    }

    public static synchronized MySingleton getInstance(Context context){
        if(mInstance == null){
            mInstance = new MySingleton(context);
        }
        return mInstance;
    }

    public void getSomeResponse(){
       responseInterface.onResponseGiven("send response");
    }


    public interface ResponseInterface{
        void onResponseGiven(String response);
    }
}

Why do I get ClassCastException telling that MainActivity cannot be casted to MySingleton.ResponseInterface??

Upvotes: 0

Views: 68

Answers (4)

KeLiuyue
KeLiuyue

Reputation: 8237

In your MySingleton class

public class MySingleton{


private static MySingleton mInstance;
private static Context mContext;
public ResponseInterface responseInterface;

private MySingleton(Context context){
    mContext = context;
}

public static synchronized MySingleton getInstance(Context context){
    if(mInstance == null){
        mInstance = new MySingleton(context);
    }
    return mInstance;
}

public void getSomeResponse(ResponseInterface responseInterface){
    this.responseInterface = responseInterface;
    responseInterface.onResponseGiven("send response");
}


public interface ResponseInterface{
    void onResponseGiven(String response);
}
}

And in your Fragment

final MySingleton mysingleton = MySingleton.getInstance(getActivity());
// edited here
mysingleton.getSomeResponse(Myfragment.this);

Upvotes: 1

Rahul
Rahul

Reputation: 212

You are getting class cast exception because in the line final MySingleton mysingleton = MySingleton.getInstance(getContext());, you are passing activity context and you are trying to cast that context to ResponseInterface. ResponseInterface is implemented by Myfragment.

To solve it: You can change MySingeton class constructor as below

private MySingleton(Context context, ResponseInterface responseInterface){
    mContext = context;
    this.responseInterface = responseInterface;

}

and the calling part (in MyFragment OnCreateView) as

final MySingleton mysingleton = MySingleton.getInstance(getContext(), this);

and in getInstance method as

 public static synchronized MySingleton getInstance(Context context, ResponseInterface responseInterface){
    if(mInstance == null){
        mInstance = new MySingleton(context, responseInterface);
    }
    return mInstance;
}

Upvotes: 0

crgarridos
crgarridos

Reputation: 9263

If you are casting MainActivity to MySingleton.ResponseInterface, you have to be sure that is implementing it.

In you actual code, MyFragment is implementing MySingleton.ResponseInterface.
I guess MainActivity doesn't

When you are calling MySingleton.getResponse(), you are sending the message to the responseInterface in your singleton. (I guess your activity, given it is a context when you create your singleton's instance).

public void getSomeResponse(){
   responseInterface.onResponseGiven("send response");
}

If you want to get the answer to your fragment, you have to ensure tha the singleton is calling to your fragment instance.

Anyway, there is a very serieus design issue. attaching a fragment/activity instance to your singleton can lead to memeory leaks if you don't free when them are destroyed. read this

Also your singleton isn't really a singleton, you create a new instance after you call getIntance every time.

Upvotes: 0

Sammekl
Sammekl

Reputation: 531

You should pass this to the getInstance method:

 MySingleton.getInstance(this);

And try to cast it to MySingleton.ResponseInterface instead of MySingleton.

Upvotes: 0

Related Questions