方向更改后,AsyncTaskLoader不调用onFinishedLoad

时间:2017-06-02 02:47:38

标签: android listview android-fragments loader asynctaskloader

一些背景资料: 我正在使用Activity> ParentFragment(包含ViewPager)>子片段。 通过添加,删除按钮动态添加子片段。 我正在使用MVP架构

实际问题: 在子片段中,我们有listview,它通过演示者使用asynctaskloader填充。

儿童片段:

//Initialize Views
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    root = inflater.inflate(R.layout.fragment_search_view_child, container, false);

.......

     mSearchViewPresenter= new SearchViewPresenter(
            getActivity(),
             new GoogleSuggestLoader(getContext()),
            getActivity().getLoaderManager(),
            this, id
    );

    SearchList list=new SearchList();
    //requestList from presenter
    searchListAdapter =new SearchViewListAdapter(getActivity(), list, this);
    listView.setAdapter(searchListAdapter);

......

    return root;
}



@Override
public void onResume(){
super.onResume();
    mSearchViewPresenter.start();
    searchBar.addTextChangedListener(textWatcher);


}

在演示者课程中,我们有:

public SearchViewPresenter(@NonNull Context context, @NonNull GoogleSuggestLoader googleloader,@NonNull LoaderManager loaderManager,
                               @NonNull SearchViewContract.View tasksView, @NonNull String id) {
        // mLoader = checkNotNull(loader, "loader cannot be null!");
        mLoaderManager = checkNotNull(loaderManager, "loader manager cannot be null");
        // mTasksRepository = checkNotNull(tasksRepository, "tasksRepository cannot be null");
        mSearchView = checkNotNull(tasksView, "tasksView cannot be null!");

        mSearchView.setPresenter(this);

        searchList=new SearchList();
        this.googleLoader=googleloader;
        this.context=context;
        this.id=loaderID;
      //  this.id=Integer.parseInt(id);
    }

    @Override
    public void start() {


        Log.d("start>initloader","log");
        mLoaderManager.restartLoader(1, null, this);
    }

    //TODO implement these when you are ready to use loader to cache local browsing history


    @Override
    public android.content.Loader<List<String>> onCreateLoader(int i, Bundle bundle) {

        int loaderid=googleLoader.getId();
        Log.d("Loader: ", "created");
        googleLoader=new GoogleSuggestLoader(context);
        googleLoader.setUrl("");
        googleLoader.setUrl(mSearchView.provideTextQuery());
        return googleLoader;
    }

    @Override
    public void onLoadFinished(android.content.Loader<List<String>> loader, List<String> data) {
        Log.d("Loader: ", "loadFinished");
        searchList.clear();
        for (int i = 0; i < data.size(); ++i) {

            searchList.addListItem(data.get(i), null, LIST_TYPE_SEARCH, android.R.drawable.btn_plus);
           Log.d("data Entry: ",i+ " is: "+searchList.getText(i));
        }
        mSearchView.updateSearchList(searchList);

    }

    @Override
    public void onLoaderReset(android.content.Loader<List<String>> loader) {

    }

此外,我们在演示者中有这个代码,该代码由正在编辑的片段视图上的edittext框触发。

  @Override
        public void notifyTextEntry() {
            //DETERMINE HOW TO GIVE LIST HERE
           // Dummy List
            Log.d("notifyTextEntry","log");
            if(googleLoader==null)googleLoader=new GoogleSuggestLoader(context);
                googleLoader.setUrl(mSearchView.provideTextQuery());
           // mLoaderManager.getLoader(id).abandon();


            mLoaderManager.getLoader(1).forceLoad();
            mLoaderManager.getLoader(1).onContentChanged();
            Log.d("length ", searchList.length().toString());
        //    googleLoader.onContentChanged();
        }

最后我们在这里有装载机:

public class GoogleSuggestLoader extends AsyncTaskLoader<List<String>>{

    /** Query URL */
    private String mUrl;
    private static final String BASE_URL="https://suggestqueries.google.com/complete/search?client=firefox&oe=utf-8&q=";
    private List<String> suggestions =new ArrayList<>();


    public GoogleSuggestLoader(Context context) {
        super(context);
        this.mUrl=BASE_URL;

    }

    public void setUrl(String mUrl){
        this.mUrl=BASE_URL+mUrl;
    };
    @Override
    protected void onStartLoading() {forceLoad(); }
    @Override
    public List<String> loadInBackground() {
        if (mUrl == null) {
            return null;
        }

        try {
            suggestions = new ArrayList<>();
            Log.d("notifyinsideLoader","log");
            String result=GoogleSuggestParser.parseTemp(mUrl);
            if(result!=null) {
                JSONArray json = new JSONArray(result);
                if (json != null) {
                JSONArray inner=new JSONArray((json.getString(1)));
                    if(inner!=null){
                        for (int i = 0; i < inner.length(); ++i) {
                            //only show 3 results
                            if(i==3)break;
                            Log.d("notifyinsideLoader",inner.getString(i));
                            suggestions.add(inner.getString(i));
                        }

                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return suggestions;
    }





}

所以问题是:

代码将数据加载到片段上的listview中。当方向改变时,加载器没有调用onLoadFinished。我测试了加载器,它正在处理数据。 我已经在演示者中尝试过forceload和onContentChanged无济于事。 如果您需要更多信息或者我应该使用像RxJava这样的其他东西让我知道。但我真的很想让这个工作。 在你问我之前我遇到过类似的问题:AsyncTaskLoader: onLoadFinished not called after orientation change但是我使用相同的id,所以这个问题不应该存在。

1 个答案:

答案 0 :(得分:0)

答案在此页AsyncTaskLoader doesn't call onLoadFinished  但没有详细说明如何转向这一点。 所以,让我在这里向其他人解释这个问题。

支持库适用于片段。因此,负责回调的类必须从支持库导入和实现正确的方法。与使用MVP相同,您的演示者必须从支持loadermanager扩展。 即:import android.support.v4.app.LoaderManager;然后实现正确的回调。

@Override
    public android.support.v4.content.Loader<List<String>> onCreateLoader(int i, Bundle bundle) {
...
return new loader
}

@Override
    public void onLoadFinished(android.support.v4.content.Loader<List<String>> loader, List<String> data) {
//do something here to your UI with data
}

其次:加载器本身必须从支持 asynctaskloader 扩展。 即:import android.support.v4.content.AsyncTaskLoader;