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..
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);
}
});