安卓3.0 - 什么是使用LoaderManager实例完全的优势是什么? [英] Android 3.0 - what are the advantages of using LoaderManager instances exactly?

查看:147
本文介绍了安卓3.0 - 什么是使用LoaderManager实例完全的优势是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用3.0,我们得到了花哨的 LoaderManager ,它处理使用 AsyncTaskLoader 的<$ C $的数据加载C> CursorLoader ,和其他定制装载机实例。但通过文档,这些阅读我只是不能让这一点:如何比只使用好老的AsyncTask 数据加载这些更好吗?

With 3.0 we got the fancy LoaderManager, which handles data loading using the AsyncTaskLoader, the CursorLoader, and other custom Loader instances. But reading through the docs for these I just couldn't get the point: how are these better than just using the good old AsyncTask for data loading?

推荐答案

那么,他们有很多容易实现,并采取一切关于生命周期管理的照顾,让少得多容易出错。

Well they are a lot simpler to implement, and take care of everything about lifecycle management so are much less error prone.

只要看看样品code,用于显示光标查询,让用户交互方式筛选的​​结果通过操作栏中的查询输入字段中设置的结果:

Just look at the sample code, for showing the result of a cursor query which lets the user interactively filter the result set through a query input field in the action bar:

public static class CursorLoaderListFragment extends ListFragment
        implements OnQueryTextListener, LoaderManager.LoaderCallbacks<Cursor> {

    // This is the Adapter being used to display the list's data.
    SimpleCursorAdapter mAdapter;

    // If non-null, this is the current filter the user has provided.
    String mCurFilter;

    @Override public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        // Give some text to display if there is no data.  In a real
        // application this would come from a resource.
        setEmptyText("No phone numbers");

        // We have a menu item to show in action bar.
        setHasOptionsMenu(true);

        // Create an empty adapter we will use to display the loaded data.
        mAdapter = new SimpleCursorAdapter(getActivity(),
                android.R.layout.simple_list_item_2, null,
                new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },
                new int[] { android.R.id.text1, android.R.id.text2 }, 0);
        setListAdapter(mAdapter);

        // Prepare the loader.  Either re-connect with an existing one,
        // or start a new one.
        getLoaderManager().initLoader(0, null, this);
    }

    @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        // Place an action bar item for searching.
        MenuItem item = menu.add("Search");
        item.setIcon(android.R.drawable.ic_menu_search);
        item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        SearchView sv = new SearchView(getActivity());
        sv.setOnQueryTextListener(this);
        item.setActionView(sv);
    }

    public boolean onQueryTextChange(String newText) {
        // Called when the action bar search text has changed.  Update
        // the search filter, and restart the loader to do a new query
        // with this filter.
        mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
        getLoaderManager().restartLoader(0, null, this);
        return true;
    }

    @Override public boolean onQueryTextSubmit(String query) {
        // Don't care about this.
        return true;
    }

    @Override public void onListItemClick(ListView l, View v, int position, long id) {
        // Insert desired behavior here.
        Log.i("FragmentComplexList", "Item clicked: " + id);
    }

    // These are the Contacts rows that we will retrieve.
    static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
        Contacts._ID,
        Contacts.DISPLAY_NAME,
        Contacts.CONTACT_STATUS,
        Contacts.CONTACT_PRESENCE,
        Contacts.PHOTO_ID,
        Contacts.LOOKUP_KEY,
    };

    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        // This is called when a new Loader needs to be created.  This
        // sample only has one Loader, so we don't care about the ID.
        // First, pick the base URI to use depending on whether we are
        // currently filtering.
        Uri baseUri;
        if (mCurFilter != null) {
            baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
                    Uri.encode(mCurFilter));
        } else {
            baseUri = Contacts.CONTENT_URI;
        }

        // Now create and return a CursorLoader that will take care of
        // creating a Cursor for the data being displayed.
        String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
                + Contacts.HAS_PHONE_NUMBER + "=1) AND ("
                + Contacts.DISPLAY_NAME + " != '' ))";
        return new CursorLoader(getActivity(), baseUri,
                CONTACTS_SUMMARY_PROJECTION, select, null,
                Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
    }

    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        // Swap the new cursor in.  (The framework will take care of closing the
        // old cursor once we return.)
        mAdapter.swapCursor(data);
    }

    public void onLoaderReset(Loader<Cursor> loader) {
        // This is called when the last Cursor provided to onLoadFinished()
        // above is about to be closed.  We need to make sure we are no
        // longer using it.
        mAdapter.swapCursor(null);
    }
}

正确地执行这项AsyncTask的完整的例子自己将要涉及更多的code ......即使如此,你要实现的东西的完整而周密的工作?例如,将您的实现保持跨越活动配置改变装入的光标所以它不需要创建新实例时被重新查询? LoaderManager /加载器就会自动为你,并且采取正确的创建和关闭基于活动的生命周期光标的照顾。

Correctly implementing this full example yourself with AsyncTask is going to involve a lot more code... and even then, are you going to implement something as complete and well working? For example, will your implementation retain the loaded Cursor across activity configuration changes so it doesn't need to be re-queried when the new instances is created? LoaderManager/Loader will do that automatically for you, as well as taking care of correctly creating and closing the Cursor based on the activity lifecycle.

另请注意,使用这种code不要求你觉得在所有关于确保长时间运行的工作进行关闭主UI线程。 LoaderManager和CursorLoader采取所有这一切对你的照顾,以确保您不会阻塞主线程同时与光标互动。要做到这一点正确,你实际上需要有两个游标对象活跃在同一时间点,这样你就可以继续与您当前的光标显示一个互动的用户界面在加载下一个显示。 LoaderManager做了所有为你。

Also notice that using this code doesn't require that you think at all about making sure long running work is performed off the main UI thread. LoaderManager and CursorLoader take care of all of that for you, ensuring you will never block the main thread while interacting with the cursor. To do this correctly you actually need to have two Cursor objects active at the same time at points, so you can continue to display an interactive UI with your current Cursor while the next one to show is being loaded. LoaderManager does all of that for you.

这仅仅是一个更简单的API - 无需知道AsyncTask的,想想需要在后台运行,没有必要去想活动周期或如何使用旧的管理指针的API的活动(没有工作,以及LoaderManager反正)。

This is just a much simpler API -- no need to know about AsyncTask and think about what needs to run in the background, no need to think about activity lifecycle or how to use the old "managed cursor" APIs in Activity (which didn't work as well as LoaderManager anyway).

(顺便说一下,不要忘记新的支持静,让您使用完整LoaderManager API在旧版本的Andr​​oid下降到1.6库!)

(Btw don't forget the new "support" static library that let you use the full LoaderManager API on older versions of Android down to 1.6!)

这篇关于安卓3.0 - 什么是使用LoaderManager实例完全的优势是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆