@newdancer

Ошибка в приложении must implement onSomeEventListener? Что не так?

Приложение валится с ошибкой:
java.lang.RuntimeException: Unable to start activity ComponentInfo{net.kinomovies.onlinemovielibrary/net.kinomovies.onlinemovielibrary.MainActivity}: java.lang.ClassCastException: net.kinomovies.onlinemovielibrary.MainActivity@117c4c7 must implement onSomeEventListener


Ошибка в классе API в этой строке: throw new ClassCastException(ctx.toString()
перед этим класс вызывается в этой строке: api = new API(getActivity());
Классы описаны ниже. Что не так?

public class MovieFragment extends Fragment implements API.APIS
{
    public static final String ARG_CATEG_NUMBER = "cat_number";
    ArrayList<Cinema> cinemas = new ArrayList<Cinema>();
    CinemaAdapter cinemaAdapter;

    // класс для retrofit
    API api;
    int numCat;
    String title="";
    int kinopoisk_id=0;

    public MovieFragment() {
        // пустой конструктор
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
    {
        // подключаем API
        api = new API(getActivity());

        View rootView = inflater.inflate(R.layout.fragment_categ, container, false);
        numCat = getArguments().getInt(ARG_CATEG_NUMBER);
        Log.d("myLogs", "numCat=" + numCat);

        // создаем адаптер
        api.getCinema(numCat, title, kinopoisk_id);
        cinemaAdapter = new CinemaAdapter(getActivity(), cinemas);

        // настраиваем список
        ListView lvMain = (ListView) rootView.findViewById(R.id.lvMain);
        lvMain.setAdapter(cinemaAdapter);

        String categTitle = getResources().getStringArray(R.array.categories_array)[numCat];

        getActivity().setTitle(categTitle);
        return rootView;
    }

    @Override
    public void getData()
    {
        cinemaAdapter.notifyDataSetChanged();
    }
}

класс API
public class API
{
    private static final String SOURCE = "http://moonwalk.cc/api";
    private final CinemaService mService;
    String api_token="тут токен";

    final String TAG = "myLogs";
    Context ctx;

    ArrayList<Cinema> cinemas = new ArrayList<Cinema>();

    public interface CinemaService {
        @GET("/movies_updates.json")
        Call<CinemaData> getCinemas(@Query("api_token") String api_token);
    }

    public interface APIS
    {
        public void getData();
    }
    APIS apis;

    public API(Context ctx) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(SOURCE)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        mService = retrofit.create(CinemaService.class);
        try {
            apis = (APIS) ctx;
        } catch (ClassCastException e) {
            throw new ClassCastException(ctx.toString()
                    + " must implement onSomeEventListener");
        }

        this.ctx = ctx;
    }

    public boolean getCinema(final int numCat, final String title, final int kinopoisk_id)
    {
        mService.getCinemas(api_token).enqueue(new Callback<CinemaData>() {
            @Override
            public void onResponse(Response<CinemaData> response, Retrofit retrofit)
            {
                cinemas.add(new Cinema(response.body().responseData.rusTitle));
                apis.getData();
            }

            @Override
            public void onFailure(Throwable t) {
                Log.d("myLogs", "Failed!!!");
            }
        });
        return true;
    }
}

class CinemaData {
    ResponseData responseData;
}

class ResponseData {
    String rusTitle;
    String match;
}
  • Вопрос задан
  • 201 просмотр
Решения вопроса 1
@razer89
Android-разработчик
Судя по логам, ваш MainActivity должен реализовывать интерфейс APIS, что скорее всего не так. Добавьте в MainActivity implements APIS, и реализуйте методы этого интерфейса
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
zagayevskiy
@zagayevskiy Куратор тега Java
Android developer at Yandex
Вы в свой API пропихиваете getActivity() в качестве контекста. И в нём проверяете
try {
            apis = (APIS) ctx;
        } catch (ClassCastException e) {
            throw new ClassCastException(ctx.toString()
                    + " must implement onSomeEventListener");
        }

Значит активити должна реализовывать этот интерфейс. Лучше бы его отдельной переменной передавать. И проверка эта некошерная, лучше писать
if (!ctx instanceof SomeMyInterface) {
    throw new IllegalStateException("ctx must imlement " +  SomeMyInterface.class.getName());
} 
myInterfaceVar = (SomeMyInterface) ctx;


Не грешите копи-пастой, хоть читайте код.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы