OkHttp在Android设备上运行时出现致命异常



我试图建立一个应用程序来复制视频流。我遇到了一个似乎无法解决的问题。

该应用程序在模拟器中运行时工作正常(尝试了一些模拟设备),但在我运行android 12L的三星android平板电脑中,它99%的时间都崩溃了。

我注意到,应用程序的工作100%的时间,当注释掉

bannerMoviesViewPager.setAdapter(bannerMoviesPagerAdapter);

我希望有人对为什么会发生这种情况有一些见解,而且,为什么它在模拟器中运行时不会崩溃。这里是代码段,我认为可能是重要的分享,但请让我知道,如果需要更多(我是相当新的堆栈溢出)

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

还有,这是进程日志的最后一部分。

输入图片描述

我将非常感谢任何帮助由于我仔细检查了是否多次读取/使用了响应体。

正如@zaitsman所指出的,当试图修改UI时,问题是在后台线程上。

我通过改变

解决了这个问题
setBannerMoviesPagerAdapter(bannerMoviesList);

到下面:

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

变化

setBannerMoviesPagerAdapter(bannerMoviesList);

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

本质上你试图修改UI(设置适配器)从后台线程(该线程由OKHttp拥有)。你需要调度回主线程。

我展示的方法是通用的,可以在任何地方工作。

或者如果你能找到你的活动,你可以做

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

最新更新