简体   繁体   English

将 retfofit 与 MVVM 一起使用时出现错误

[英]I am getting error while using retfofit with MVVM

I am trying to fetch data by using retrofit with MVVM Architecture.我正在尝试使用带有 MVVM 架构的 retrofit 来获取数据。 When I wanted to print the data on console, it works.当我想在控制台上打印数据时,它可以工作。

But when I wanna use them on the RecyclerView , I get this error:但是当我想在RecyclerView上使用它们时,我收到了这个错误:

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.movieapp, PID: 4275 android.os.NetworkOnMainThreadException. E/AndroidRuntime:致命异常:主进程:com.example.movieapp,PID:4275 android.os.NetworkOnMainThreadException。

Here is my codes:这是我的代码:

MovieRepository电影资料库

public class MovieRepository {

private static MovieService movieService;
private final MutableLiveData<List<Movie>> listOfPopularMovie ;

private static MovieRepository newsRepository;


public static MovieRepository getInstance(){
    if(newsRepository == null){
        newsRepository=new MovieRepository();
    }
    return newsRepository;
}
public MovieRepository(){
    movieService= RetrofitService.getMovieService();
    listOfPopularMovie=new MutableLiveData<>();
}

public MutableLiveData<List<Movie>> getListOfPopularMovie(String key,int page) {
    Call<MovieResponse> popularMovies= movieService.getPopularMovie(key,page);
    popularMovies.enqueue(new Callback<MovieResponse>() {
        @Override
        public void onResponse(Call<MovieResponse> call, Response<MovieResponse> response) {
            listOfPopularMovie.setValue(response.body().getResults());
        }

        @Override
        public void onFailure(Call<MovieResponse> call, Throwable t) {
            listOfPopularMovie.postValue(null);
        }
    });
    return listOfPopularMovie;
}

MainViewModel主视图模型

public class MainViewModel extends AndroidViewModel {
private MutableLiveData<List<Movie>> listOfPopularMovies = new MutableLiveData<>();
private MovieRepository movieRepository;


public MainViewModel(@NonNull Application application) {
    super(application);
    movieRepository = MovieRepository.getInstance();
}

public MutableLiveData<List<Movie>> getListOfPopularMovies(String key, int page) {
    listOfPopularMovies=movieRepository.getListOfPopularMovie(key,page);
    return listOfPopularMovies;
}

MovieAdapter电影适配器

public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MovieViewHolder> {
private List<Movie> movies;
private Context mContext;
public MovieAdapter(Context context){
    mContext=context;
}

@NonNull
@Override
public MovieViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view= LayoutInflater.from(mContext).inflate(R.layout.item_view,parent,false);

    return new MovieViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull MovieViewHolder holder, int position) {
    Movie movie=movies.get(position);
    String currentTitle=movie.getTitle();
    String imageUrl="https://image.tmdb.org/t/p/original";
    imageUrl +=movie.getBackdrop_path();
    try {
        URL url=new URL(imageUrl);
        Bitmap bmp=BitmapFactory.decodeStream(url.openConnection().getInputStream());
        Drawable drawable=new BitmapDrawable(mContext.getResources(),bmp);
        holder.image.setBackground(drawable);
        holder.title.setText(currentTitle);
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

}



@Override
public int getItemCount() {
    if(movies == null)
        return 0;
    return movies.size();
}
public void setMovie(List<Movie> taskEntries) {
    movies = taskEntries;
    notifyDataSetChanged();
}

class MovieViewHolder extends RecyclerView.ViewHolder {

    LinearLayout image;
    TextView title;
    public MovieViewHolder(@NonNull View itemView) {
        super(itemView);
        image=itemView.findViewById(R.id.movie_image);
        title=itemView.findViewById(R.id.movie_title);
    }
}

MainActivity主要活动

public class MainActivity extends AppCompatActivity {

MovieAdapter movieAdapter;
RecyclerView recyclerView;
MainViewModel mainViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    recyclerView= findViewById(R.id.recycler_view);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    movieAdapter= new MovieAdapter(this);
    recyclerView.setAdapter(movieAdapter);
    DividerItemDecoration decoration = new DividerItemDecoration(getApplicationContext(), VERTICAL);
    recyclerView.addItemDecoration(decoration);
    mainViewModel= new ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication())).get(MainViewModel.class);
    mainViewModel.getListOfPopularMovies("9e2629973011b0744ce3b589dff1fb32",1).observe(this, new Observer<List<Movie>>() {
        @Override
        public void onChanged(List<Movie> movies) {
           movieAdapter.setMovie(movies);
        }
    });


}

Your exception happened because you use network in UI thread.您的异常发生是因为您在 UI 线程中使用网络。
I found the problem in your MovieAdapter code.我在您的MovieAdapter代码中发现了问题。

@Override
public void onBindViewHolder(@NonNull MovieViewHolder holder, int position) {
    ......................
    URL url = new URL(imageUrl);
    Bitmap bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
    Drawable drawable = new BitmapDrawable(mContext.getResources(),bmp);
    holder.image.setBackground(drawable);
    .............................
}

So you used url.openConnection() code in onBindViewHolder method of MovieAdapter class.因此,您在 MovieAdapter class 的 onBindViewHolder 方法中使用了 url.openConnection() 代码。 But onBindViewHolder is called in UI thread.但是 onBindViewHolder 在 UI 线程中被调用。

So, Answer is you should not call this function in onBindViewHolder method.所以,答案是你不应该在 onBindViewHolder 方法中调用这个 function 。

My suggestion is you can use image load library such as Glide or Picasso.我的建议是您可以使用 Glide 或 Picasso 等图像加载库。

https://github.com/bumptech/glide https://github.com/bumptech/glide
https://github.com/square/picasso https://github.com/square/picasso

if you use Glide, your onBindViewHolder method like this.如果你使用 Glide,你的 onBindViewHolder 方法是这样的。

Glide.with(holder.image.getContext()).load(imageUrl).into(holder.image);

I hope this will be helpful.我希望这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我在使用 android studio 时会出现此错误。? - Why am I getting this error while using android studio.? 为什么在使用URLLoader时突然出现流错误? - Why am I suddenly getting stream error while using URLLoader? 在 android 工作室中使用 CoordinatorTabLayout 时出现错误 - I am getting error while using CoordinatorTabLayout in android studio 启动应用程序时出现此错误 - I am getting this error while launching the app 使用此 map.setMyLocationEnabled(true) 时,我总是遇到错误; 它不工作 - I am always getting error while using this map.setMyLocationEnabled(true); its not working 在Android中使用getParcelable检索位图文件时出现错误 - I am getting an error while retrieving the Bitmap file using getParcelable in android 使用自签名证书时出现SSLHandshakeException和CertPathValidatorException错误 - I am getting a SSLHandshakeException and CertPathValidatorException error while using self signed certificate 为什么在使用realm.executeTransactionAsync()方法时出现编译时错误? - Why I am getting compile time error while using realm.executeTransactionAsync() method? 我在尝试使用 Room 数据库时收到此错误消息 - I am getting this error messsage while trying to use Room database 在读取nfc标签时出现此错误? - While reading nfc tags i am getting this error?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM