Home > other >  OkHttp Fatal Exception when running on Android device
OkHttp Fatal Exception when running on Android device

Time:11-08

I am trying to build an app to replicate a video streamer. I have encountered an issue that can't seem to solve.

The app is working fine when run in an emulator (tried a few emulated devices) but it is crashing 99% of the time in my Samsung android tablet running android 12L.

I have noticed that the app works 100% of the time, when commenting out the

bannerMoviesViewPager.setAdapter(bannerMoviesPagerAdapter);

I was hoping someone has some insight of why this could happen, and also, why does it not crash when running in an emulator. Here are segments of code that I think might be important to share, but please let me know if more is needed (i am quite new at stack overflow)

private void setBannerMoviesPagerAdapter(List<BannerMovies> bannerMoviesList){
    bannerMoviesViewPager = (ViewPager) findViewById(R.id.banner_viewPager);
    bannerMoviesPagerAdapter = new BannerMoviesPagerAdapter(this, bannerMoviesList);
    bannerMoviesViewPager.setAdapter(bannerMoviesPagerAdapter); // COMMENT THIS LINE AND IT WORKS

    //tabLayout.setupWithViewPager(bannerMoviesViewPager);

    Timer sliderTimer = new Timer();
    sliderTimer.scheduleAtFixedRate(new AutoSlider(), 4000, 6000);
    tabLayout.setupWithViewPager(bannerMoviesViewPager, true);
}
public void fetch_json_banner_list(){
    System.out.println("Attempting to fetch JSON");
    final String url = "http://*serverIP*:80/api/movie";
    Request request = new Request.Builder().url(url).build();
    OkHttpClient client = new OkHttpClient();

    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(@NonNull Call call, @NonNull IOException e) {
            System.out.println("Failed to execute request");
        }

        @Override
        public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
            bannerMoviesList = new ArrayList<>();
            String body = response.body().string();
            Gson gson = new GsonBuilder().create();

            Type allFilmsType = new TypeToken<ArrayList<Film>>(){}.getType();
            List<Film> allFilms = gson.fromJson(body, allFilmsType);

            for(Film film : allFilms){
                System.out.println(film.getArtwork());
                System.out.println(film.getArtwork().equals("https://media.movieassets.com/static/images/items/movies/posters/216767680a8a72fff4a12c484c6ac589.jpg"));
                bannerMoviesList.add(new BannerMovies(film.getMovieId(), film.getTitle(), film.getSynopsis(), film.getArtwork().trim(), "https://ia800306.us.archive.org/35/items/PopeyeAliBaba/PopeyeAliBaba_512kb.mp4"));
            }
            setBannerMoviesPagerAdapter(bannerMoviesList);
        }
    });
}
public class BannerMoviesPagerAdapter extends PagerAdapter {

    Context context;
    List<BannerMovies> bannerMoviesList;

    public BannerMoviesPagerAdapter(Context context, List<BannerMovies> bannerMoviesList) {
        this.context = context;
        this.bannerMoviesList = bannerMoviesList;
        System.out.println("GETS HERE....");
    }

    @Override
    public int getCount() {
        return bannerMoviesList.size();
    }

Also, here is the last part of the logcat for the process..

enter image description here

I would very much appreciate any help Thanks

I double checked if I was reading / using the response body more than once.

CodePudding user response:

Change

setBannerMoviesPagerAdapter(bannerMoviesList);

To

new android.os.Handler(android.os.Looper.getMainLooper()).post({
   setBannerMoviesPagerAdapter(bannerMoviesList);
});

Essentially you are trying to modify the UI (set adapter) from the background thread (that thread is owned by OKHttp). You need to dispatch back to main thread.

The method I showed is universal and will work from anywhere.

Alternatively if you can find your activity you can do

getActivity().runOnUiThread({
    setBannerMoviesPagerAdapter(bannerMoviesList);
});

CodePudding user response:

As zaitsman pointed out, the problem was being on the background thread whilst trying to modify the UI.

Solved it by changing

setBannerMoviesPagerAdapter(bannerMoviesList);

to

Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
  @Override
  public void run() {
    setBannerMoviesPagerAdapter(bannerMoviesList);
  }
});
  • Related