ButterKnife问题在android中

时间:2017-11-29 07:23:09

标签: android butterknife android-mvp

我正在使用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();
}    

}

2 个答案:

答案 0 :(得分: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/

答案 1 :(得分:0)

在以下情况下,我也有同样的问题:

  1. 打开片段A
  2. 打开片段B(很快,在 片段A出现)
  3. 重新打开片段A

第一次打开片段A时,改造将调用API,在调用完成之前,移至片段B,然后片段A将被称为onDestroyView。在此方法中,黄油刀为unbinded。返回到片段A时,将调用API的响应过程,现在该组件为空,因为它已取消绑定。

解决方案:使用call.cancel()

移至片段B(onDestroyView)时取消了请求
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();
}