Android加载器LoaderManager.LoaderCallbacks的使用

来源:互联网 发布:婚纱摄影电子相册软件 编辑:程序博客网 时间:2024/05/17 20:03

转自:http://blog.csdn.net/deng0zhaotai/article/details/22486423

LoaderManager.LoaderCallbacks是3.0之后出现的新特性,通过LoaderManager.LoaderCallbacks接口可以很轻松的实现异步加载数据到Fragment或Activity 中,Loaders提供了回调机制onLoadFinished()通知最终的运行结果,有点类似AsyncTask类,但由于Loader对于并发可以用过Loader管理器统一管理,所以更适合批量处理多个异步任务的处理(当然内部仍然是多线程)。要使用Loader就要实现LoaderManager.LoaderCallbacks接口,并实现它的抽象方法


下面是我加载通话记录的Demo,实现了过滤拨入、拨出、未接、所有,删除单条记录,拨号功能,实现效果图



目录结构


ListView中每个item的布局listview_item.xml

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <ImageView  
  7.         android:id="@+id/bt_icon"  
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="wrap_content"  
  10.         android:layout_centerVertical="true"  
  11.         android:layout_marginLeft="10dp"  
  12.         android:background="#00000000"  
  13.         android:contentDescription="@string/content_description"  
  14.         android:src="@drawable/calllog_incoming" />  
  15.   
  16.     <TextView  
  17.         android:id="@+id/tv_name"  
  18.         android:layout_width="wrap_content"  
  19.         android:layout_height="wrap_content"  
  20.         android:layout_marginLeft="10dp"  
  21.         android:layout_marginTop="2dp"  
  22.         android:layout_toRightOf="@id/bt_icon"  
  23.         android:textSize="23sp" />  
  24.   
  25.     <TextView  
  26.         android:id="@+id/tv_number"  
  27.         android:layout_width="wrap_content"  
  28.         android:layout_height="wrap_content"  
  29.         android:layout_alignLeft="@id/tv_name"  
  30.         android:layout_below="@id/tv_name"  
  31.         android:layout_marginBottom="2dp"  
  32.         android:textColor="#7f7f7f"  
  33.         android:textSize="16sp" />  
  34.   
  35.     <TextView  
  36.         android:id="@+id/tv_date"  
  37.         android:layout_width="wrap_content"  
  38.         android:layout_height="wrap_content"  
  39.         android:layout_alignTop="@id/tv_number"  
  40.         android:layout_marginLeft="10dp"  
  41.         android:layout_toRightOf="@id/tv_number"  
  42.         android:ellipsize="end"  
  43.         android:textColor="#7f7f7f"  
  44.         android:textSize="16sp" />  
  45.   
  46.     <ImageButton  
  47.         android:id="@+id/btn_delete"  
  48.         android:layout_width="wrap_content"  
  49.         android:layout_height="wrap_content"  
  50.         android:layout_alignParentRight="true"  
  51.         android:layout_centerVertical="true"  
  52.         android:layout_marginRight="10dp"  
  53.         android:background="#00000000"  
  54.         android:contentDescription="@string/content_description"  
  55.         android:focusableInTouchMode="false"  
  56.         android:src="@drawable/cl_delete_selector" />  
  57.   
  58.     <ImageButton  
  59.         android:id="@+id/btn_call"  
  60.         android:layout_width="wrap_content"  
  61.         android:layout_height="wrap_content"  
  62.         android:layout_centerVertical="true"  
  63.         android:layout_marginRight="5dp"  
  64.         android:layout_toLeftOf="@id/btn_delete"  
  65.         android:background="#00000000"  
  66.         android:contentDescription="@string/content_description"  
  67.         android:focusableInTouchMode="false"  
  68.         android:src="@drawable/cl_call_selector" />  
  69.   
  70. </RelativeLayout>  

整个Activity的布局文件

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     tools:context=".MainActivity" >  
  6.   
  7.     <TextView  
  8.         android:id="@+id/tv_text"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:text="@string/hello_world" />  
  12.   
  13.     <Button  
  14.         android:id="@+id/btn_all"  
  15.         android:layout_width="wrap_content"  
  16.         android:layout_height="wrap_content"  
  17.         android:layout_below="@id/tv_text"  
  18.         android:text="@string/all" />  
  19.   
  20.     <Button  
  21.         android:id="@+id/btn_incoming"  
  22.         android:layout_width="wrap_content"  
  23.         android:layout_height="wrap_content"  
  24.         android:layout_below="@id/tv_text"  
  25.         android:layout_marginLeft="20dp"  
  26.         android:layout_toRightOf="@id/btn_all"  
  27.         android:text="@string/incoming" />  
  28.   
  29.     <Button  
  30.         android:id="@+id/btn_outcoming"  
  31.         android:layout_width="wrap_content"  
  32.         android:layout_height="wrap_content"  
  33.         android:layout_below="@id/btn_all"  
  34.         android:layout_marginTop="10dp"  
  35.         android:text="@string/outcoming" />  
  36.   
  37.     <Button  
  38.         android:id="@+id/btn_missed"  
  39.         android:layout_width="wrap_content"  
  40.         android:layout_height="wrap_content"  
  41.         android:layout_alignLeft="@id/btn_incoming"  
  42.         android:layout_below="@id/btn_all"  
  43.         android:layout_marginTop="10dp"  
  44.         android:layout_toRightOf="@id/btn_outcoming"  
  45.         android:text="@string/missed" />  
  46.   
  47.     <View  
  48.         android:id="@+id/line_layout"  
  49.         android:layout_width="match_parent"  
  50.         android:layout_height="2dp"  
  51.         android:layout_below="@id/btn_missed"  
  52.         android:background="#000000" >  
  53.     </View>  
  54.   
  55.     <ListView  
  56.         android:id="@+id/lv_list"  
  57.         android:layout_width="match_parent"  
  58.         android:layout_height="match_parent"  
  59.         android:layout_below="@id/line_layout"  
  60.         android:clipToPadding="false"  
  61.         android:divider="#ff553311"  
  62.         android:dividerHeight="2dp"  
  63.         android:fadingEdge="none"  
  64.         android:paddingTop="10dp" />  
  65.   
  66. </RelativeLayout>  

ListView对应的适配器MyCursorAdapter.java

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.dzt.loaderdemo;  
  2.   
  3. import java.text.SimpleDateFormat;  
  4. import java.util.Date;  
  5. import java.util.Locale;  
  6.   
  7. import android.content.Context;  
  8. import android.content.Intent;  
  9. import android.database.Cursor;  
  10. import android.net.Uri;  
  11. import android.provider.CallLog;  
  12. import android.util.Log;  
  13. import android.view.LayoutInflater;  
  14. import android.view.View;  
  15. import android.view.ViewGroup;  
  16. import android.view.View.OnClickListener;  
  17. import android.widget.CursorAdapter;  
  18. import android.widget.ImageButton;  
  19. import android.widget.ImageView;  
  20. import android.widget.TextView;  
  21.   
  22. class MyCursorAdapter extends CursorAdapter {  
  23.   
  24.     private static final String TAG = "dzt";  
  25.     private final Context mContext;  
  26.   
  27.     public MyCursorAdapter(Context context, Cursor c) {  
  28.         this(context, c, true);  
  29.         // TODO Auto-generated constructor stub  
  30.     }  
  31.   
  32.     public MyCursorAdapter(Context context, Cursor c, boolean autoRequery) {  
  33.         super(context, c, autoRequery);  
  34.         // TODO Auto-generated constructor stub  
  35.         mContext = context;  
  36.     }  
  37.   
  38.     public MyCursorAdapter(Context context, Cursor c, int flags) {  
  39.         super(context, c, flags);  
  40.         // TODO Auto-generated constructor stub  
  41.         mContext = context;  
  42.     }  
  43.   
  44.     @Override  
  45.     public View newView(Context context, Cursor cursor, ViewGroup parent) {  
  46.         // TODO Auto-generated method stub  
  47.         LayoutInflater inflater = LayoutInflater.from(context);  
  48.         return inflater.inflate(R.layout.listview_item, parent, false);  
  49.     }  
  50.   
  51.     @Override  
  52.     public void bindView(View view, Context context, Cursor cursor) {  
  53.         // TODO Auto-generated method stub  
  54.         if (cursor == null)  
  55.             return;  
  56.         final String id = cursor.getString(0);  
  57.         String number = cursor.getString(1);  
  58.         String name = cursor.getString(2);  
  59.         int type = cursor.getInt(3);  
  60.         String date = cursor.getString(4);  
  61.         ImageView TypeView = (ImageView) view.findViewById(R.id.bt_icon);  
  62.         TextView nameCtrl = (TextView) view.findViewById(R.id.tv_name);  
  63.         if (name == null) {  
  64.             nameCtrl.setText(mContext.getString(R.string.name_unknown));  
  65.         } else {  
  66.             nameCtrl.setText(name);  
  67.         }  
  68.         TextView numberCtrl = (TextView) view.findViewById(R.id.tv_number);  
  69.         numberCtrl.setText(number);  
  70.         String value = ComputeDate(date);  
  71.         TextView dateCtrl = (TextView) view.findViewById(R.id.tv_date);  
  72.         dateCtrl.setText(value);  
  73.         switch (type) {  
  74.         case CallLog.Calls.INCOMING_TYPE:  
  75.             TypeView.setImageResource(R.drawable.calllog_incoming);  
  76.             break;  
  77.         case CallLog.Calls.OUTGOING_TYPE:  
  78.             TypeView.setImageResource(R.drawable.calllog_outcoming);  
  79.             break;  
  80.         case CallLog.Calls.MISSED_TYPE:  
  81.             TypeView.setImageResource(R.drawable.calllog_missed);  
  82.             break;  
  83.         case 4// CallLog.Calls.VOICEMAIL_TYPE  
  84.   
  85.             break;  
  86.         default:  
  87.             break;  
  88.         }  
  89.   
  90.         ImageButton dailBtn = (ImageButton) view.findViewById(R.id.btn_call);  
  91.         dailBtn.setTag(number);  
  92.         dailBtn.setOnClickListener(new OnClickListener() {  
  93.   
  94.             @Override  
  95.             public void onClick(View v) {  
  96.                 // TODO Auto-generated method stub  
  97.                 // Intent.ACTION_CALL_PRIVILEGED 由于Intent中隐藏了,只能用字符串代替  
  98.                 Intent intent = new Intent(Intent.ACTION_CALL, Uri.fromParts(  
  99.                         "tel", (String) v.getTag(), null));  
  100.                 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  101.                 mContext.startActivity(intent);  
  102.             }  
  103.         });  
  104.   
  105.         ImageButton deleteBtn = (ImageButton) view  
  106.                 .findViewById(R.id.btn_delete);  
  107.         deleteBtn.setOnClickListener(new OnClickListener() {  
  108.   
  109.             @Override  
  110.             public void onClick(View v) {  
  111.                 // TODO Auto-generated method stub  
  112.                 // 根据ID进行记录删除  
  113.                 String where = CallLog.Calls._ID + "=?";  
  114.                 String[] selectionArgs = new String[] { id };  
  115.                 int result = mContext.getContentResolver().delete(  
  116.                         CallLog.Calls.CONTENT_URI, where, selectionArgs);  
  117.                 Log.d(TAG, "11result = " + result);  
  118.             }  
  119.         });  
  120.     }  
  121.   
  122.     private String ComputeDate(String date) {  
  123.         long callTime = Long.parseLong(date);  
  124.         long newTime = new Date().getTime();  
  125.         long duration = (newTime - callTime) / (1000 * 60);  
  126.         String value;  
  127.         // SimpleDateFormat sfd = new  
  128.         // SimpleDateFormat("yyyy-MM-dd HH:mm:ss",  
  129.         // Locale.getDefault());  
  130.         // String time = sfd.format(callTime);  
  131.         // Log.d(TAG, "[MyCursorAdapter--ComputeDate] time = " + time);  
  132.         // 进行判断拨打电话的距离现在的时间,然后进行显示说明  
  133.         if (duration < 60) {  
  134.             value = duration + "分钟前";  
  135.         } else if (duration >= 60 && duration < MainActivity.DAY) {  
  136.             SimpleDateFormat sdf = new SimpleDateFormat("HH:mm",  
  137.                     Locale.getDefault());  
  138.             value = sdf.format(new Date(callTime));  
  139.   
  140.             // value = (duration / 60) + "小时前";  
  141.         } else if (duration >= MainActivity.DAY  
  142.                 && duration < MainActivity.DAY * 2) {  
  143.             value = "昨天";  
  144.         } else if (duration >= MainActivity.DAY * 2  
  145.                 && duration < MainActivity.DAY * 3) {  
  146.             value = "前天";  
  147.         } else if (duration >= MainActivity.DAY * 7) {  
  148.             SimpleDateFormat sdf = new SimpleDateFormat("MM/dd",  
  149.                     Locale.getDefault());  
  150.             value = sdf.format(new Date(callTime));  
  151.         } else {  
  152.             value = (duration / MainActivity.DAY) + "天前";  
  153.         }  
  154.         return value;  
  155.     }  
  156. }  

加载器是放在MainActivity.java类当中

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.dzt.loaderdemo;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.LoaderManager;  
  5. import android.content.CursorLoader;  
  6. import android.content.Loader;  
  7. import android.database.Cursor;  
  8. import android.os.Bundle;  
  9. import android.provider.CallLog;  
  10. import android.util.Log;  
  11. import android.view.View;  
  12. import android.view.View.OnClickListener;  
  13. import android.widget.Button;  
  14. import android.widget.ListView;  
  15.   
  16. /** 
  17.  * 使用加载器加载通话记录 
  18.  *  
  19.  * @author Administrator 
  20.  *  
  21.  */  
  22. public class MainActivity extends Activity {  
  23.   
  24.     private static final String TAG = "dzt";  
  25.     // 查询指定的条目  
  26.     private static final String[] CALLLOG_PROJECTION = new String[] {  
  27.             CallLog.Calls._ID, CallLog.Calls.NUMBER, CallLog.Calls.CACHED_NAME,  
  28.             CallLog.Calls.TYPE, CallLog.Calls.DATE };  
  29.     static final int DAY = 1440// 一天的分钟值  
  30.     private static final int ALL = 0// 默认显示所有  
  31.     private static final int INCOMING = CallLog.Calls.INCOMING_TYPE; // 来电  
  32.     private static final int OUTCOMING = CallLog.Calls.OUTGOING_TYPE; // 拔号  
  33.     private static final int MISSED = CallLog.Calls.MISSED_TYPE; // 未接  
  34.     private ListView mListView;  
  35.     private MyLoaderListener mLoader = new MyLoaderListener();  
  36.     private MyCursorAdapter mAdapter;  
  37.     private int mCallLogShowType = ALL;  
  38.     private boolean m_FinishLoaderFlag = false// 第一次加载完成  
  39.   
  40.     @Override  
  41.     protected void onCreate(Bundle savedInstanceState) {  
  42.         super.onCreate(savedInstanceState);  
  43.         setContentView(R.layout.activity_main);  
  44.         initWidgets();  
  45.         initMyLoader();  
  46.     }  
  47.   
  48.     private void initWidgets() {  
  49.         mListView = (ListView) findViewById(R.id.lv_list);  
  50.         Button btn = (Button) findViewById(R.id.btn_all);  
  51.         btn.setOnClickListener(new buttonListener());  
  52.         btn = (Button) findViewById(R.id.btn_incoming);  
  53.         btn.setOnClickListener(new buttonListener());  
  54.         btn = (Button) findViewById(R.id.btn_outcoming);  
  55.         btn.setOnClickListener(new buttonListener());  
  56.         btn = (Button) findViewById(R.id.btn_missed);  
  57.         btn.setOnClickListener(new buttonListener());  
  58.         mAdapter = new MyCursorAdapter(MainActivity.thisnull);  
  59.         mListView.setAdapter(mAdapter);  
  60.     }  
  61.   
  62.     private void initMyLoader() {  
  63.         getLoaderManager().initLoader(0null, mLoader);  
  64.     }  
  65.   
  66.     /** 
  67.      * 实现一个加载器 
  68.      *  
  69.      * @author Administrator 
  70.      *  
  71.      */  
  72.     private class MyLoaderListener implements  
  73.             LoaderManager.LoaderCallbacks<Cursor> {  
  74.   
  75.         @Override  
  76.         public Loader<Cursor> onCreateLoader(int id, Bundle args) {  
  77.             // TODO Auto-generated method stub  
  78.             m_FinishLoaderFlag = false;  
  79.             CursorLoader cursor = new CursorLoader(MainActivity.this,  
  80.                     CallLog.Calls.CONTENT_URI, CALLLOG_PROJECTION, nullnull,  
  81.                     CallLog.Calls.DEFAULT_SORT_ORDER);  
  82.             Log.d(TAG, "MyLoaderListener---------->onCreateLoader");  
  83.             return cursor;  
  84.         }  
  85.   
  86.         @Override  
  87.         public void onLoadFinished(Loader<Cursor> loader, Cursor data) {  
  88.             // TODO Auto-generated method stub  
  89.             if (data == null)  
  90.                 return;  
  91.             Cursor tempData = data;  
  92.             if (tempData.getCount() == 0) {  
  93.                 Log.d(TAG,  
  94.                         "MyLoaderListener---------->onLoadFinished count = 0");  
  95.                 mAdapter.swapCursor(null);  
  96.                 return;  
  97.             }  
  98.             if (m_FinishLoaderFlag) {  
  99.                 tempData = null;  
  100.                 String selection = null;  
  101.                 String[] selectionArgs = null;  
  102.                 if (mCallLogShowType == INCOMING) {  
  103.                     selection = CallLog.Calls.TYPE + "=?";  
  104.                     selectionArgs = new String[] { "1" };  
  105.                 } else if (mCallLogShowType == OUTCOMING) {  
  106.                     selection = CallLog.Calls.TYPE + "=?";  
  107.                     selectionArgs = new String[] { "2" };  
  108.                 } else if (mCallLogShowType == MISSED) {  
  109.                     selection = CallLog.Calls.TYPE + "=?";  
  110.                     selectionArgs = new String[] { "3" };  
  111.                 }  
  112.                 tempData = getContentResolver().query(  
  113.                         CallLog.Calls.CONTENT_URI, CALLLOG_PROJECTION,  
  114.                         selection, selectionArgs,  
  115.                         CallLog.Calls.DEFAULT_SORT_ORDER);  
  116.             }  
  117.             mAdapter.swapCursor(tempData);  
  118.             Log.d(TAG,  
  119.                     "MyLoaderListener---------->onLoadFinished data count = "  
  120.                             + data.getCount());  
  121.             m_FinishLoaderFlag = true;  
  122.         }  
  123.   
  124.         @Override  
  125.         public void onLoaderReset(Loader<Cursor> loader) {  
  126.             // TODO Auto-generated method stub  
  127.             Log.d(TAG, "MyLoaderListener---------->onLoaderReset");  
  128.             mAdapter.swapCursor(null);  
  129.         }  
  130.     }  
  131.   
  132.     private class buttonListener implements OnClickListener {  
  133.   
  134.         @Override  
  135.         public void onClick(View v) {  
  136.             // TODO Auto-generated method stub  
  137.             switch (v.getId()) {  
  138.             case R.id.btn_all:  
  139.                 allCalllog();  
  140.                 break;  
  141.             case R.id.btn_incoming:  
  142.                 incomingCalllog();  
  143.                 break;  
  144.             case R.id.btn_outcoming:  
  145.                 outcomingCalllog();  
  146.                 break;  
  147.             case R.id.btn_missed:  
  148.                 missedCalllog();  
  149.                 break;  
  150.             default:  
  151.                 break;  
  152.             }  
  153.         }  
  154.     }  
  155.   
  156.     private void allCalllog() {  
  157.         mCallLogShowType = ALL;  
  158.         String selection = null;  
  159.         String[] selectionArgs = null;  
  160.         Cursor allCursor = getContentResolver().query(  
  161.                 CallLog.Calls.CONTENT_URI, CALLLOG_PROJECTION, selection,  
  162.                 selectionArgs, CallLog.Calls.DEFAULT_SORT_ORDER);  
  163.         mAdapter.swapCursor(allCursor);  
  164.     }  
  165.   
  166.     private void incomingCalllog() {  
  167.         mCallLogShowType = INCOMING;  
  168.         String selection = CallLog.Calls.TYPE + "=?";  
  169.         String[] selectionArgs = new String[] { "1" };  
  170.         Cursor incomingCursor = getContentResolver().query(  
  171.                 CallLog.Calls.CONTENT_URI, CALLLOG_PROJECTION, selection,  
  172.                 selectionArgs, CallLog.Calls.DEFAULT_SORT_ORDER);  
  173.         mAdapter.swapCursor(incomingCursor);  
  174.     }  
  175.   
  176.     private void outcomingCalllog() {  
  177.         mCallLogShowType = OUTCOMING;  
  178.         String selection = CallLog.Calls.TYPE + "=?";  
  179.         String[] selectionArgs = new String[] { "2" };  
  180.         Cursor outcomingCursor = getContentResolver().query(  
  181.                 CallLog.Calls.CONTENT_URI, CALLLOG_PROJECTION, selection,  
  182.                 selectionArgs, CallLog.Calls.DEFAULT_SORT_ORDER);  
  183.         mAdapter.swapCursor(outcomingCursor);  
  184.     }  
  185.   
  186.     private void missedCalllog() {  
  187.         mCallLogShowType = MISSED;  
  188.         String selection = CallLog.Calls.TYPE + "=?";  
  189.         String[] selectionArgs = new String[] { "3" };  
  190.         Cursor missedCursor = getContentResolver().query(  
  191.                 CallLog.Calls.CONTENT_URI, CALLLOG_PROJECTION, selection,  
  192.                 selectionArgs, CallLog.Calls.DEFAULT_SORT_ORDER);  
  193.         mAdapter.swapCursor(missedCursor);  
  194.     }  
  195. }  
加载器的使用就是重写三个回调函数,并在加载完时设置Adapter的Cursor,使用Loader之后,只要数据源发生变化,就会自动调用onLoadFinished(),此时listview也会自动刷新


完整的Demo

http://download.csdn.net/detail/deng0zhaotai/7116173


0 0