1 ContentProvider的生命周期

直接看代码实例比较清晰,主要是onCreate和CRUD(增删改查)以及getType。首先需要在manifest声明,android:authorities是contentprovider的唯一标识。

(1) query、update、insert、delete存在多线程并发访问,需要做好线程同步。

(2) contentprovider的oncreate方法在application的oncreate方法之前执行。

访问contentprovider如下:

Uri uri = Uri.parse("content://com.cwx.test.Provider");getContentResolver().query(uri,null,null,null,null);
public class StudentContentProvider extends ContentProvider {    //这里的AUTHORITY就是我们在AndroidManifest.xml中配置的authorities    private static final String AUTHORITY = "com.cwx.test.provider";    //匹配成功后的匹配码1    private static final int MATCH_CODE = 100;    //匹配成功后的匹配码2    private static final int MATCH_CODE1 = 101;    private static UriMatcher uriMatcher;    private StudentDao studentDao;        private TeacherDao teacherDao;    //数据改变后指定通知的Uri    private static final Uri NOTIFY_URI = Uri.parse("content://" + AUTHORITY + "/student");    private static final Uri NOTIFY_URI1 = Uri.parse("content://" + AUTHORITY + "/teacher");    static {        //匹配不成功返回NO_MATCH(-1)        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);        //添加我们需要匹配的uri        uriMatcher.addURI(AUTHORITY,"student", MATCH_CODE);        //继续添加        uriMatcher.addURI(AUTHORITY,"teacher", MATCH_CODE1);    }    @Override    public boolean onCreate() {        studentDao = StudentDao.getInstance(getContext());        teacherDao = TeacherDao.getInstance(getContext());        return false;    }    @Nullable    @Override    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection,                        @Nullable String[] selectionArgs, @Nullable String sortOrder) {        int match = uriMatcher.match(uri);        if (match == MATCH_CODE){            Cursor cursor = studentDao.queryStudent();            return cursor;        } else if(match == MATCH_CODE1){            Cursor cursor = teacherDao.queryTeacher();            return cursor;        }        return null;    }    @Nullable    @Override    public String getType(@NonNull Uri uri) {        return null;    }    @Nullable    @Override    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {        if (uriMatcher.match(uri) == MATCH_CODE){            studentDao.insertStudent(values);            notifyChange();        } else if(uriMatcher.match(uri) == MATCH_CODE1){            teacherDao.insertTeacher(values);            notifyChange1();        }        return null;    }    @Override    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {        if (uriMatcher.match(uri) == MATCH_CODE){            int delCount = studentDao.deleteStudent();            notifyChange();            return delCount;        }  else if(uriMatcher.match(uri == MATCH_CODE1){            int delCount = teacherDao.deleteTeacher();            notifyChange1();            return delCount;        }        return 0;    }    @Override    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection,                      @Nullable String[] selectionArgs) {        return 0;    }    private void notifyChange(){        getContext().getContentResolver().notifyChange(NOTIFY_URI,null);    }        private void notifyChange1(){        getContext().getContentResolver().notifyChange(NOTIFY_URI1,null);    }}

2 ContentProvider的onCreate和CRUD运行在哪个线程?它们是线程安全的吗?如何保证线程安全?

2.1运行线程

onCreate、query、update、insert、delete和getType这六个方法均运行在contentprovider进程当中,除了onCreate由系统回调运行在主线程当中,其他五个方法均运行在binder线程池当中。是否线程安全这个要区分contentprovider是否是跨进程访问的:(1)如果是跨进程访问,由于CRUD运行在binder线程池所以是线程不安全的 (2)如果是进程内部调用,根据binder的原理会直接对象调用,这时候是运行在调用者线程也就不存在线程安全问题了。

2.2保证线程安全

3 ContentProvider的内部存储只能是sqlite吗?

ContentProvider的内部存储不一定是sqlite,它可以是任意数据,比如contentprovider存储文件图片:

/*     * 为了简单起见,这里直接将asset/pic.*png拷贝到了程序的ExternalFilesDir,实际中应该是从网络上下载图片到ExternalFilesDir。     */ public class FileProvider extends ContentProvider {        @Override      public boolean onCreate() {          File file = new File(getContext().getExternalFilesDir(null), "pic.png");          if (!file.exists()) {              AssetManager assetManager = getContext().getAssets();                try {                  InputStream is = assetManager.open("pic.png");                  OutputStream os = new BufferedOutputStream(new FileOutputStream(file));                  byte [] buf = new byte[1024];                  int len = 0;                  while ((len = is.read(buf)) > 0) {                      os.write(buf, 0, len);                  }                  is.close();                  os.close();              } catch (IOException e) {                  e.printStackTrace();                  return false;              }          }          return true;      }        @Override      public Cursor query(Uri uri, String[] projection, String selection,              String[] selectionArgs, String sortOrder) {          // TODO Auto-generated method stub          return null;      }        @Override      public String getType(Uri uri) {          if (uri.toString().endsWith(".png")) {              return "image/png";          }          return null;      }        /*     * 就是做一次映射,返回uri指定的文件的文件描述符     */      @Override      public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {          if ("image/png".equals(getType(uri))) {              File file = new File(getContext().getExternalFilesDir(null), uri.getPath());              if (file.exists()) {                  return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);              }          }          throw new FileNotFoundException(uri.getPath());      }            @Override      public Uri insert(Uri uri, ContentValues values) {          // TODO Auto-generated method stub          return null;      }        @Override      public int delete(Uri uri, String selection, String[] selectionArgs) {          // TODO Auto-generated method stub          return 0;      }        @Override      public int update(Uri uri, ContentValues values, String selection,              String[] selectionArgs) {          // TODO Auto-generated method stub          return 0;      }  }  

调用:

public static final Uri URI = Uri.parse("content://com.ipjmc.demo.fileprovider/pic.png");  //通过ContentResolver获取图片的输入流,再转化为Bitmap  InputStream is = getContentResolver().openInputStream(URI);  Bitmap bitmap = BitmapFactory.decodeStream(is); 

 

更多相关文章

  1. 详解Android(安卓)Handler的使用
  2. UI与线程交互
  3. android中锁屏后代码不运行的问题
  4. android上运行gcc
  5. android线程模型文章集合
  6. android 异步加载
  7. Android实现掷骰子效果
  8. Android(安卓)自动化测试—robotium(七)Ant 构建脚本
  9. Mms模块ConversationList流程分析(1)

随机推荐

  1. Android(安卓)开发之v4库冲突问题解决方
  2. Android 基本按钮
  3. Android(安卓)& Java 注释模板的设置
  4. android 发送邮件到QQEmail
  5. Android Studio 编译报错:Manifest merger
  6. android的Android Please ensure that ad
  7. android平台下基于ffmpeg的swscale模块实
  8. 【转】创建和使用Android library工程
  9. Android UI 之 clipRect
  10. HelloWorldAndroid几个控件