我试图建立一个应用程序来复制视频流。我遇到了一个似乎无法解决的问题。
该应用程序在模拟器中运行时工作正常(尝试了一些模拟设备),但在我运行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);
});