练习随笔 16.09.30

来源:互联网 发布:java有趣好玩的代码 编辑:程序博客网 时间:2024/04/29 23:17

今天来复习做联系人


先来清单配置文件

<!-- 配置联系人读写权限 -->

    <uses-permission android:name="android.permission.READ_CONTACTS" />

    <uses-permission android:name="android.permission.WRITE_CONTACTS" />

/**1 */

创建一个包 专门放实体类封装数据 entity

  --创建Contact类 封装联系人信息

  --重点是处理头像

/**2*/

通过ContactsContract API查询所有的联系人信息

public class Contactmanager {//通过ContactsContract API查询所有的联系人信息public static List<Contact> getContacts(Context context){List<Contact> contacts = new ArrayList<Contact>();//创建一个内容解析器来访问内容提供者 提供数据ContentResolver resolver = context.getContentResolver();//调用query方法  下面这几行都是根据query参数 逐个添加的Uri uri =ContactsContract.Contacts.CONTENT_URI;//方法1String[] projection =new String[]{ContactsContract.Contacts._ID,ContactsContract.Contacts.PHOTO_ID};String[] projection =new String[]{"_id","photo_id"}; //projection 对应数据库中的列Cursor cursor =resolver.query(uri, projection, null, null, null);//游标换行while (cursor.moveToNext()) {Contact contact=new Contact();//int id = cursor.getInt(0); 非整形可能报异常 int id = cursor.getInt(cursor.getColumnIndex("_id"));int photoid = cursor.getInt(cursor.getColumnIndex("photo_id"));contact.setId(id);contact.setPhotoid(photoid);//把联系人对象加到联系人集合中contacts.add(contact);}cursor.close();return contacts;}}

   

/**3*/

单元测试

  --对项目中某一个独立业务模块进行单独的测试

  --创建一个单元测试的测试案例(AcdroidTestCase)

  --要在清单文件中进行相关的配置测试包:全是提示出来的 =。=

  <application >里
        <uses-library android:name="android.test.runner"/>

  <application >下

    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.example.myYouLu"
        ></instrumentation>

   

    新建测试包,类

/** * 单元测试案例 * */public class MyTestCase extends AndroidTestCase {public void test(){List<Contact> contacts =Contactmanager.getContacts(getContext());for (Contact contact : contacts) {Log.i("TAG", "contacts="+contacts);}}}
android Junit


   

/**4*/

添加内层循环,为联系人参数添加数据

//从数据库粘贴“”中的内容public final static String MIMETYPE_NAME="vnd.android.cursor.item/name";public final static String MIMETYPE_EMAIL="vnd.android.cursor.item/email_v2";public final static String MIMETYPE_PHONE="vnd.android.cursor.item/phone_v2";public final static String MIMETYPE_ADDRESS="vnd.android.cursor.item/postal-address_v2";
V2的是正确的 全部复制

//根据联系人的账户查该联系人的详细数据信息//name phone address email//data表Uri dataUri=ContactsContract.Data.CONTENT_URI;//DATA1列有很多数据,要拿到类型做判断,MIMETYPE这列是类型,所以拿这两列String[] projection2=new String[]{Data.MIMETYPE,Data.DATA1};String selection =Data.RAW_CONTACT_ID+"=?";Cursor cursor2 =resolver.query(dataUri,projection2, selection, new String[]{String.valueOf(id)}, null);//null是排序//外层循环查联系人ID 内层循环查询联系人数据while(cursor2.moveToNext()){String mimetype = cursor2.getString(cursor2.getColumnIndex(Data.MIMETYPE));//"mimetype"String data1 = cursor2.getString(cursor2.getColumnIndex(Data.DATA1));//"data1"if (MIMETYPE_NAME.equals(mimetype)) {contact.setName(data1);}else if (MIMETYPE_EMAIL.equals(mimetype)) {contact.setEmail(data1);}else if (MIMETYPE_PHONE.equals(mimetype)) {contact.setPhone(data1);}else if (MIMETYPE_ADDRESS.equals(mimetype)) {contact.setAddress(data1);}}cursor2.close();
contact.setName(data1);复制的时候别忘了改成其他set,要不全空


/**5*/

    //稀疏数组 用来替代HashMap的更高效的数据集合
    public static SparseArray<Contact> cacheContact=new SparseArray<Contact>();


在外循环中加入缓存判断

//判断缓存中是否存在该联系人if (cacheContact.get(id)!=null) {//如果在缓存保存了联系人信息//直接从缓存中取出联系人对象并加入联系人集合//直接返回contacts.add(cacheContact.get(id));continue;}


/**6*/

很多模块都需要数据适配器,所以我们可以封装出一个“母版”

/** * 封装出一个母版适配器 是其他适配器的父类 * 用泛型类<T>: 类型参数化 可以传递不同的实参 减少拆装箱次数 * */public abstract class MyBaseAdapter<T> extends BaseAdapter {/**1*///存放要适配数据 加1个private List<T> datas = new ArrayList<T>();//集合是私有的,子类继承不到,所以封装出一个公有方法,控制集合的数据,公开一个添加数据的方式public void addDatas(T t){if (t!=null) {datas.add(t);notifyDataSetChanged();}}//加1组//预留一个是否清空的布尔值 为真先清空再添加public void addDatas(List<T> ts,boolean isClear){if (isClear) {datas.clear();datas.addAll(ts);}else{datas.addAll(ts);}notifyDataSetChanged();}//获得适配器当中的所有数据public List<T> getDatas(){return this.datas;}//删除数据public void removeData(T t){if (datas.contains(t)){datas.remove(t);notifyDataSetChanged();}}/**1*//**2*///上下文参数 布局解析器protected Context context=null; protected LayoutInflater  layoutInflater =null;public MyBaseAdapter(Context context) {this.context=context;layoutInflater=LayoutInflater.from(context);}/**2*/@Overridepublic int getCount() {// TODO Auto-generated method stubreturn datas.size();}//类型改成T@Overridepublic T getItem(int position) {// TODO Auto-generated method stubreturn datas.get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}//改成抽象方法--》改成抽象泛型类@Overridepublic abstract View getView(int position, View convertView, ViewGroup parent);}


/**7*/

写个联系人子适配器

/** * 此处开始考虑滑动view对象优化,避免oom(内存溢出) * 滑动view是gridview的高度必须是machparent 不能使包裹 否则每个都要重新计算高度 * */public class ContactAdapter extends MyBaseAdapter<Contact> {//调用父类含参构造方法,直接初始化,不是空对象了。public ContactAdapter(Context context) {super(context);}//子类继承父类,要重写所有父类的抽象方法,或把子类也定义为抽象@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder=null;//此处if-else为优化处理部分if (convertView==null) {holder=new ViewHolder();convertView=layoutInflater.inflate(R.layout.inflate_contact_item, null);holder.imageview_header=(ImageView) convertView.findViewById(R.id.imageView_contact_header);holder.textview_name=(TextView) convertView.findViewById(R.id.textView_contact_name);//封装到Tag,方便提取convertView.setTag(holder);}else{//不为空说明缓存里有view对象holder=(ViewHolder) convertView.getTag();}//拿到数据项Contact contact=getItem(position);//添加到holderholder.textview_name.setText(contact.getName());//先设置个默认头像 再处理问题holder.imageview_header.setImageResource(R.drawable.ic_contact);return convertView;}public class ViewHolder{ImageView imageview_header=null;TextView textview_name=null;}}

/**8*/

头像是编号 所以现在还不显示 还要根据编号再查

在ContactManager里设置头像

/**4  * 根据头像id查头像 * @param context * @param photoid * @return */public static Bitmap getPhotobyPhotoid(Context context,int photoid){/**5 修改*///Bitmap bitmap=null;Bitmap bitmap=cachePhoto.get(photoid);if (bitmap==null) {if (photoid==0) {//bitmap是空 所以要赋值成默认图片bitmap=BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_contact);}else{ContentResolver resolver=context.getContentResolver();Uri uri =Data.CONTENT_URI;String[] projection =new String[]{Data.DATA15};String selection =Data._ID+"=?";Cursor cursor=resolver.query(uri, projection, selection, new String[]{String.valueOf(photoid)}, null);if (cursor.moveToNext()) {//二进制数组byte bolb[]=cursor.getBlob(0);bitmap=BitmapFactory.decodeByteArray(bolb, 0, bolb.length);/**5 */if (bitmap!=null) {//把图片存入缓存cachePhoto.put(photoid, bitmap);}}cursor.close();/**5 这俩括号也是后加的*/}}return bitmap;}

加入缓存优化机制 包括上面代码块的if判断

//Lrucache缓存机制是内部存储的数据都是强引用,在设计的缓存空间不满时,数据不会被回收,满了,回收最近最少使用的缓存//设计缓存的最大空间 mbpublic static int maxSize=1024*1024*4;public static LruCache<Integer, Bitmap> cachePhoto =new LruCache<Integer, Bitmap>(maxSize){//计算每一幅被缓存图片的大小protected int sizeOf(Integer key, Bitmap value) {return value.getRowBytes()*value.getHeight();};};




0 0
原创粉丝点击