android之Loaders初步

来源:互联网 发布:单片机独立按键电路图 编辑:程序博客网 时间:2024/05/19 12:11

Loaders 是android 3.0新引入的api和接口。它具有以下特点:

1.     Loaders用于所有的Activity和Fragment;

2.     提供异步数据装载机制;

3.     监控他们的来源数据变化情况,在数据发生变化的时候传递新的结果;

4.     自动重连到最后一个数据加载器游标,因此不需要重新查询数据。

从以上特点感觉可以很方便的异步获取数据。想一下handler和asyTask吧。上面的描述好像很美好。

Lorders API主要包括以下接口和类。

LoaderManager:管理着一个Activity或者Fragment中的一个或多个Loader实例,每个Activity或者Fragment只有对应一个LoaserManager。

LoaderManager.LoaderCallbacks.一个回调接口,需要自己实现,接口定义了一些初始化的方法和取得数据后的回调方法。

Loader:一个抽象类,负责异步加载数据。

AsyncTaskLoader:继承Loader,使用asyTask来加载数据。

CursorLoader:AsyncTaskLoader的子类。可以用来查询ContentResolver,并返回一个Cursor。

 

故从以上看出,使用CursorLoader可以很方便的异步获取数据并坚持其变化,当然这局限于ContentResolver,不过这可以用到很多android的原生数据了,如联系人、图片等。

 

如下的一个例子来自android官方文档,简单的说明了如何使用CursorLoader。

 

import android.app.ListFragment;

import android.app.LoaderManager.LoaderCallbacks;

import android.content.CursorLoader;

import android.content.Loader;

import android.database.Cursor;

import android.net.Uri;

import android.os.Bundle;

import android.provider.ContactsContract.Contacts;

import android.text.TextUtils;

import android.util.Log;

import android.view.Menu;

import android.view.MenuInflater;

import android.view.MenuItem;

import android.view.View;

import android.widget.ListView;

import android.widget.SearchView;

import android.widget.SearchView.OnQueryTextListener;

import android.widget.SimpleCursorAdapter;

 

public  class CursorLoaderListFragment extends ListFragment

 

implements OnQueryTextListener, 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 publicvoid 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 publicvoid 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 publicboolean onQueryTextSubmit(String query) {

 

// Don't care about this.

 

return true;

 

}

 

 

 

@Override publicvoid 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);

 

}}

 

 

Loader可以自动的监控数据源的变化,这无疑是一个亮点。这点在CursorLoader中表现的淋漓尽致。但是在对于实际应用来说,数据源很可能来自Internet,当然不可能是Cursor。(你当然可以自己取数据,然后存起来如db中,然后转化为cursor)。这时就需要用AsyncTaskLoader,但是它是一个抽象类,所以需要自己实现,你需要自己实现它的监控数据变化机制,这绝不是一个简单的问题。而Loaders从这点来说就是定义了一系列的接口框架,需要自己实现这些机制。例子见

http://developer.android.com/reference/android/content/AsyncTaskLoader.html

0 0
原创粉丝点击