1

我正在butterknife使用retrofit. 当我通过网络调用连续加载片段时,我的片段在视图上以空指针崩溃。我已经onDestroyView()在片段中实现了 unbind ...?

使用findviewbyid. 我正在使用 MVP 。

Unbinder unbinder;
@BindView(R.id.swipe_refresh_layout)
SwipeRefreshLayout swipeRefreshLayout;

@BindView(R.id.recycler_view_shop)
RecyclerView recyclerView;

@BindView(R.id.ll_content)
LinearLayout layoutContent;

@BindView(R.id.ll_no_data)
LinearLayout layoutNoData;

@BindView(R.id.tv_category_heading)
TextView categoryHeading;

private HomeActivity activity;
private ProgressDialog progressDialog;
DrListFragmentPresenter presenter;


public DrListFragment() {
    // Required empty public constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View rootView = inflater.inflate(R.layout.fragment_dr, container, false);
    // bind view using butter knife
    unbinder = ButterKnife.bind(this, rootView);

    LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.addItemDecoration(new DividerItemDecoration(getFragment().getActivity(),DividerItemDecoration.VERTICAL));

    activity = (HomeActivity) getActivity();

    presenter = new DrListFragmentPresenterImpl(this);
    return rootView;
}

@Override
public Fragment getFragment() {
    return this;
}


@Override
public void setCategoriesDetailsAdapter(CategoryWiseItemListingAdapter adapter) {
    recyclerView.setAdapter(adapter);
}





@Override
public void onDestroyView() {
    super.onDestroyView();

    // unbind the view to free some memory
    unbinder.unbind();
}    

}
4

2 回答 2

0

我对以下场景有同样的问题:

  1. 开放片段 A
  2. 打开片段 B(很快,在片段 A 中的数据出现之前)
  3. 重新打开片段 A

第一次打开 Fragment A 时,retrofit 会调用 API,在调用完成之前,会移动到 Fragment B,然后 Fragment A 会被调用onDestroyView。在这种方法中,黄油刀是unbinded. 返回片段 A 时,调用 API 的响应过程,现在组件为空,因为它已被解除绑定。

解决方案:使用移动到片段 B (onDestroyView) 时取消请求call.cancel()

private Call call;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View rootView = inflater.inflate(R.layout.fragment_dr, container, false);
    // bind view using butter knife
    unbinder = ButterKnife.bind(this, rootView);

    call = downloadService.downloadFileWithDynamicUrlSync(fileUrl);
    call.enqueue(){
        // error occured here
    }
}

@Override
public void onDestroyView() {
    super.onDestroyView();

    // unbind the view to free some memory
    unbinder.unbind();

    // cancel request
    call.cancel();
}    
于 2019-08-15T15:34:15.283 回答
0

查看project gradle

dependencies {
    classpath 'com.android.tools.build:gradle:2.3.3'
    // add this in your code
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'  
}

查看app gradle

apply plugin: 'com.android.application'
apply plugin: 'android-apt'  // add this 

...
dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
    exclude group: 'com.android.support', module: 'support-annotations'
    })

    compile 'com.jakewharton:butterknife:8.6.0'
    // add this 
    apt 'com.jakewharton:butterknife-compiler:8.6.0
}

并且在版本中8.8.1

您可以将其添加到app gradle

apply plugin: 'com.android.library'
apply plugin: 'com.jakewharton.butterknife'
...
dependencies {
     compile 'com.jakewharton:butterknife:8.8.1'
     annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}

并将其添加到project gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.jakewharton:butterknife-gradle-plugin:8.8.1'
    }
}

你可以检查

https://github.com/JakeWharton/butterknife

https://jakewharton.github.io/butterknife/

于 2017-11-29T07:28:14.533 回答