Reputation: 5739
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
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
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
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
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