(4.1.38)Android Loader 技术的简单实用

从Android3.0开始,Android SDK提供了Loader技术,使用Loader技术可以很容易进行数据的异步加载。Loader技术为我们提供的核心类有:

  • LoaderManager:可以通过Activity或者的Fragment的getLoaderManager()方法得到LoaderManager,用来对Loader进行管理,一个Activity或者Fragment只能有一个LoaderManager。
  • LoaderManager.LoaderCallbacks:用于同LoaderManager进行交互,可以在其中创建Loader对象。
  • AsyncTaskLoader:抽象类,可以进行异步加载数据的Loader,貌似内部也是通过AsynTask实现的,可以通过继承它构建自己的Loader,也可以使用现有的子类,例如异步查询数据库可以使用CursorLoader。

    使用Loader一般可以经过以下步骤:

    1、初始化Loader,可以使用initLoader(intid, Bundle args, LoaderManager.LoaderCallbackscallback);方法进行初始化。
    id:标识Loader的ID,一个Activity或者Fragment只能有一个LoaderManager,但可以有多个Loader,通过ID区 分。在新建Loader时,如果发现已经有相同ID的Loader就会复用该Loader,而不会重新创建。
    args:传给新建Loader的参数。 

    Callback:回调接口。


    2、实现LoaderManager.LoaderCallbacks中的方法,LoaderManager.LoaderCallbacks中需要实现的方法有:
    publicLoader onCreateLoader(int id, Bundle args):创建新的Loader,id为LoaderID,如果已经有相同ID的Loader就会复用该Loader,而不会重新创建。 args为初始化时传递的参数。该方法开始异步查询,并返回一个泛型类,如果是查询数据库可以返回一个CursorLoader,可以返回自定义的Loader。public voidonLoadFinished(Loader loader, D data):异步查询结束的会调用这个方法,并返回查询结果 data。public void onLoaderReset(Loader loader): 当调用Loader.reset()将Loader数据清空时,但在系统销毁Loader时会自动调用Loader.reset()方法,我们一般不需要手动调用,只需要在onLoaderReset方法中,将使用Loader的移除。

    3、使用 restartLoader(intid, Bundle args, LoaderManager.LoaderCallbacks callback)方法进行数据更新,和初始化一个,如果有相同id的Loader存在,会复用Loader,并清空原有Loader中的数据,如果没有就新建一个。这个方法一般使用在需要更新数据时,例如下面例子中,在搜索关键改变时,需要调用这个方法,从新异步查询数据。


    下面一个例子使用CursorLoader查询联系人名字,并显示在ListActivity中,在ActionBar上放置了一个SearchView可以根据联系人姓名关键字查询联系人。

    Activity代码如下:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    public class MainActivity extends ListActivity implements LoaderManager.LoaderCallbacks<cursor>, SearchView.OnQueryTextListener {
    private  SimpleCursorAdapter cursorAdapter;
         private String filterName= null ;
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super .onCreate(savedInstanceState);
             setContentView(R.layout.activity_main);
             TextView tv= (TextView) findViewById(android.R.id.empty);
             tv.setText( "请稍后" );
     
             cursorAdapter= new SimpleCursorAdapter( this ,
                     android.R.layout.simple_list_item_2,
                     null ,
                     new String[]{ContactsContract.Contacts.DISPLAY_NAME},
                     new int []{android.R.id.text1}, 0 );
              setListAdapter(cursorAdapter);
             //初始化Loader
               getLoaderManager().initLoader( 0 , null , this );
         }
     
     
         @Override
         public Loader<cursor> onCreateLoader( int id, Bundle args) {
             Uri uri;
             String[] pro= new String[]{ ContactsContract.Contacts.DISPLAY_NAME,ContactsContract.Contacts._ID};
             if (TextUtils.isEmpty(filterName)){
                 uri= ContactsContract.Contacts.CONTENT_URI;
             } else {
                 uri=Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI,Uri.encode(filterName));
             }
             //创建Loader对象,开始异步加载数据
             return new CursorLoader( this ,uri,pro, null , null , null );
         }
     
         @Override
         public void onLoadFinished(Loader<cursor> loader, Cursor data) {
             //得到异步加载数据,更新Adapter
             cursorAdapter.swapCursor(data);
         }
     
         @Override
         public void onLoaderReset(Loader<cursor> loader) {
             //移除adapter使用的Loader,系统会释放不再使用的Loader
             cursorAdapter.swapCursor( null );
         }
     
     
         @Override
         public boolean onCreateOptionsMenu(Menu menu) {
             getMenuInflater().inflate(R.menu.menu_main,menu);
             SearchView v= (SearchView) menu.findItem(R.id.menu_search).getActionView();
             v.setOnQueryTextListener( this );
             return true ;
         }
     
         @Override
         public boolean onQueryTextSubmit(String query) {
             return true ;
         }
     
         @Override
         public boolean onQueryTextChange(String newText) {
             filterName=newText;
             //使用新的Loader(清空旧的数据)
             getLoaderManager().restartLoader( 0 , null , this );
             return false ;
         }
    }</cursor></cursor></cursor></cursor>

    菜单资源文件:

    ?
    1
    2
    3
    <menu xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http://schemas.android.com/tools" tools:context= ".MainActivity" >
         <item android:actionviewclass= "android.widget.SearchView" android:id= "@+id/menu_search" android:showasaction= "ifRoom|collapseActionView" android:title= "搜索" tools:ignore= "AppCompatResource" >
    </item></menu>

    最后来个效果图:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值