在ViewModel中调用Retrofit 2会导致内存泄漏吗?

时间:2018-09-05 20:21:41

标签: android retrofit2 viewmodel

问题很简短:使用ViewModel异步调用改造2会导致内存泄漏吗?

就像下面的例子一样。

ShowsAsynViewModel.java

公共类ShowsAsyncViewModel扩展了ViewModel {

private static final String TAG = "ShowsAsyncViewModel";

private MutableLiveData<List<Show>> shows;

public LiveData<List<Show>> getShows() {
    if (shows == null) {
        shows = new MutableLiveData<>();
        loadShows();
    }
    return shows;
}

private void loadShows() {
    // Do an asynchronous operation to fetch users.
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(TvMazeService.BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    TvMazeService service = retrofit.create(TvMazeService.class);
    service.getShows().enqueue(new Callback<List<Show>>() {
        @Override
        public void onResponse(Call<List<Show>> call, Response<List<Show>> response) {
            if (response.isSuccessful()) {
                List<Show> showList = response.body();
                if (showList != null) {
                    shows.setValue(showList);
                }
            } else {
                Log.i(TAG, "onResponse: Error code: " + response.code() + " - error message: " + response.message());
            }
        }

        @Override
        public void onFailure(Call<List<Show>> call, Throwable t) {
            t.printStackTrace();
            Log.i(TAG, "onFailure: Failed to connect: " + t.getMessage());
        }
    });
}
}

RetrofitActivity.java

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_retrofit);

    ShowsAsyncViewModel model = ViewModelProviders.of(this).get(ShowsAsyncViewModel.class);
    model.getShows().observe(this, new Observer<List<Show>>() {
        @Override
        public void onChanged(@Nullable List<Show> shows) {
            // Do something with the result
        }
    });
}

这就是我所注意到的。

  1. 如果我使用RetrofitActivity.java onCreate方法中的相同方法调用Retrofit 2。我最终会发生大量内存泄漏,因为每次重新创建活动时都会调用改造。
  2. 如果我使用将WeakReference保留到上下文的私有静态内部类来调用翻新2,则不会因为WeakReference导致内存泄漏,并且还因为用户多次旋转屏幕而未多次调用此方法。 / li>
  3. 使用此ShowsAsyncViewModel并没有引起内存泄漏,可能是因为即使用户多次旋转屏幕,此方法也仅被调用一次。我想确保这不会导致内存泄漏。

1 个答案:

答案 0 :(得分:0)

是的,它可能导致内存泄漏。 想象一个场景,其中您从附加到ViewModel的{​​{1}}进行网络呼叫。在调用完成之前,不是为了更改配置而是通过调用Activity来销毁该活动。 即使Activity和ViewModel都被破坏,该调用仍将继续执行。

为防止这种情况,您可以按以下方式修改finish()(kotlin代码)

ShowsAsynViewModel.java