美文网首页
从事Android以来的相关总结2-Android技能

从事Android以来的相关总结2-Android技能

作者: 重炎 | 来源:发表于2017-04-25 19:57 被阅读0次

    Android的进程与线程:

    1、进程的生命周期:

    1)、进程的创建及回收:

    进程是被系统创建的,当内存不足的时候,又会被系统回收

    2)、进程的级别:

    Foreground Process前台进程

    Visible Process可视进程

    Service Process服务进程:可以提高级别的

    Background Process后台进程

    Empty Process空进程(无组件启动,做进程缓存使用,恢复速度快)

    Android技能

    «熟练掌握Android四大组件,常用的布局文件,自定义控件等

    Android中4大组件是:ContentProvider、Activity、BroadcastReceiver和Service

    清单文件:

    1、所有的应用程序必须要有清单文件

    在manifest节点下需要声明当前应用程序的包名

    2、包名:声明包的名字,必须唯一

    如果两个应用程序的包名和签名都相同,后安装的会覆盖先安装的

    3、声明的程序的组件(4大组件)

    其中比较特殊的是广播接收者,可以不在清单文件中配置,可以通过代码进行注册

    4、声明程序需要的权限:保护用户的隐私

    5、可以控制服务在单独的进程中的,四大组件都可以配置这个属性process

    在组件节点配置process:

    如:android:process="xxx.ooo.xxx"

    比如说:处理图片的时候,会很耗内存,就需要在单独的新的进程中,可以减少内存溢出的几率

    一、ContentProvider内容提供者

    1、特点

    ①、可以将应用中的数据对外进行共享;

    ②、数据访问方式统一,不必针对不同数据类型采取不同的访问策略;

    ③、内容提供者将数据封装,只暴露出我们希望提供给其他程序的数据(这点有点类似Javabeans);

    ④、内容提供者中数据更改可被监听;

    2、创建内容提供者

    Ø定义类继承ContentProvider,根据需要重写其内容方法(6个方法):

    lonCreate()创建内容提供者时,会调用这个方法,完成一些初始化操作;

    lcrud相应的4个方法用于对外提供CRUD操作;

    lgetType()返回当前Url所代表数据的MIME类型:

    返回的是单条记录:以vnd.android.cursor.item/开头,如:vnd.android.cursor.item/person

    返回的是多条记录:以vnd.android.cursor.dir/开头,如:vnd.android.cursor.dir/person

    Ø在清单文件的节点下进行配置,标签中需要指定name、authorities、exported属性

    lname:为全类名;

    lauthorities:是访问Provider时的路径,要唯一;

    lexported:用于指示该服务是否能够被其他应用程序组件调用或跟它交互

    ØURI代表要操作的数据,由scheme、authorites、path三部分组成:

    lcontent://com.itheima.sqlite.provider/person

    lscheme:固定为content,代表访问内容提供者;

    lauthorites:节点中的authorites属性;

    lpath:程序定义的路径,可根据业务逻辑定义;

    Ø操作URI的UriMather与ContentUris工具类:

    当程序调用CRUD方法时会传入Uri

    lUriMatcher:表示URI匹配器,可用于添加Uri匹配模式,与匹配Uri(见下代码);

    lContentUris:用于操作Uri路径后面的ID部分,2个重要的方法:

    1.withAppendedId(uri, id)为路径加上ID部分;

    2.parseId(uri)用于从路径中获取ID部分;

    示例代码(内容提供者类):

    public classHeimaProvider extends ContentProvider {

    private static final int PERSON = 1;//匹配码

    private static final int STUDENT = 2;//匹配码

    private static final int PERSON_ID = 3;//匹配码

    private MyHelper helper;

    /** Uri匹配器*/

    private UriMatcher uriMatcher = newUriMatcher(UriMatcher.NO_MATCH);

    @Override

    public boolean onCreate() {

    System.out.println("onCreate...");

    helper = newMyHelper(getContext());

    // ==添加uri匹配模式,设置匹配码(参数3)Uri如果匹配就会返回相应的匹配码==

    uriMatcher.addURI("com.itheima.sqlite.provider","person", PERSON);

    uriMatcher.addURI("com.itheima.sqlite.provider","#", PERSON_ID);// #表示匹配数字,*表示匹配文本

    uriMatcher.addURI("com.itheima.sqlite.provider","student", STUDENT);

    return true;

    }

    @Override

    public Uri insert(Uri uri, ContentValuesvalues) {

    SQLiteDatabase db =helper.getWritableDatabase();

    switch (uriMatcher.match(uri)) {//匹配uri

    case PERSON:

    long id =db.insert("person", "id", values);

    db.close();

    returnContentUris.withAppendedId(uri, id);//在原uri上拼上id,生成新的uri并返回;

    case STUDENT:

    long insert =db.insert("student", "id", values);

    System.out.println("数据文件中,没有student表,也不会报错");

    db.close();

    returnContentUris.withAppendedId(uri, insert);//为路径上,加上ID

    default:

    throw newIllegalArgumentException(String.format("Uri:%s不是合法的uri地址", uri));

    }

    }

    @Override

    public int delete(Uri uri, Stringselection, String[] selectionArgs) {

    SQLiteDatabase db =helper.getWritableDatabase();

    switch (uriMatcher.match(uri)) {//匹配uri

    case PERSON_ID:

    long parseId =ContentUris.parseId(uri);//获取传过来的ID值

    selection = "id=?";//设置查询条件

    selectionArgs = newString[] { parseId + "" };//查询条件值

    case PERSON:

    int delete =db.delete("person", selection, selectionArgs);

    db.close();

    return delete;

    default:

    throw newIllegalArgumentException(String.format("Uri:%s不是合法的uri地址", uri));

    }

    }

    @Override

    public int update(Uri uri, ContentValuesvalues, String selection, String[] selectionArgs) {

    SQLiteDatabase db =helper.getWritableDatabase();

    switch (uriMatcher.match(uri)) {

    case PERSON_ID:

    long parseId =ContentUris.parseId(uri);//获取传过来的ID值

    selection ="id=?";//设置查询条件

    selectionArgs = newString[] { parseId + "" };//查询条件值

    case PERSON:

    int update =db.update("person", values, selection, selectionArgs);

    db.close();

    return update;

    default:

    throw newIllegalArgumentException(String.format("Uri:%s不是合法的uri地址", uri));

    }

    }

    @Override

    public Cursor query(Uri uri, String[]projection, String selection, String[] selectionArgs, String sortOrder) {

    SQLiteDatabase db =helper.getWritableDatabase();

    switch (uriMatcher.match(uri)) {

    case PERSON_ID:

    // ==根据ID查询==

    long parseId =ContentUris.parseId(uri);//获取传过来的ID值

    selection ="id=?";//设置查询条件

    selectionArgs = newString[] { parseId + "" };//查询条件值

    case PERSON:

    Cursor cursor =db.query("person", projection, selection, selectionArgs, null, null,sortOrder);

    // ==注意:此处的db与cursor不能关闭==

    return cursor;

    default:

    throw newIllegalArgumentException(String.format("Uri:%s不是合法的uri地址", uri));

    }

    }

    //返回传入URI的类型,可用于测试URI是否正确

    @Override

    public String getType(Uri uri) {

    switch (uriMatcher.match(uri)) {

    case PERSON_ID:

    return"vnd.android.cursor.item/person";//表示单条person记录

    case PERSON:

    return"vnd.android.cursor.dir/person";//表单多个person记录

    default:

    return null;

    }

    }

    }

    清单中的配置:

    android:exported="true"

    android:name="com.itheima.sqlite.provider.HeimaProvider"

    android:authorities="com.itheima.sqlite.provider" />

    authorities可以配置成如下形式(系统联系人的):

    android:authorities="contacts;com.android.contacts"

    “;”表示的是可使用contacts,与com.android.contacts

    3、内容解析者ContentResolver

    �通过Context获得ContentResolver内容访问者对象(内容提供者的解析器对象);

    �调用ContentResolver对象的方法即可访问内容提供者

    测试类代码:

    public class HeimaProviderTest extends AndroidTestCase {

    /**测试添加数据*/

    public void testInsert() {

    ContentResolver resolver =this.getContext().getContentResolver();

    Uri uri =Uri.parse("content://com.itheima.sqlite.provider/person");

    ContentValues values = newContentValues();

    values.put("name","小翼");

    values.put("balance",13000);

    Uri insert = resolver.insert(uri,values);//获取返回的uri,如:content://com.itheima.sqlite.provider/7

    System.out.println(insert);

    }

    /**测试删除*/

    public void testRemove() {

    ContentResolver resolver = this.getContext().getContentResolver();

    Uri uri =Uri.parse("content://com.itheima.sqlite.provider/person");

    int count = resolver.delete(uri,"id=?", new String[] { 3 + "" });

    System.out.println("删除了" + count + "行");

    }

    /**测试更新*/

    public void testUpdate() {

    ContentResolver resolver =this.getContext().getContentResolver();

    Uri uri =Uri.parse("content://com.itheima.sqlite.provider/person");

    ContentValues values = newContentValues();

    values.put("name","小赵update");

    values.put("balance",56789);

    int update = resolver.update(uri,values, "id=?", new String[] { 6 + "" });

    System.out.println("更新了" + update + "行");

    }

    /**测试查询*/

    public void testQueryOne() {

    ContentResolver resolver =this.getContext().getContentResolver();

    Uri uri = Uri.parse("content://com.itheima.sqlite.provider/person");

    Cursor c = resolver.query(uri, newString[] { "name", "balance" }, "id=?", newString[] { 101 + "" }, null);

    if (c.moveToNext()) {

    System.out.print(c.getString(0));

    System.out.println("" + c.getInt(1));

    }

    c.close();

    }

    /**测试查询全部*/

    public void testQueryAll() {

    ContentResolver resolver =this.getContext().getContentResolver();

    Uri uri =Uri.parse("content://com.itheima.sqlite.provider/person");

    Cursor c = resolver.query(uri, newString[] { "id", "name", "balance" }, null, null,"name desc");

    while (c.moveToNext()) {

    System.out.println(c.getInt(0)+ ", " + c.getString(1) + ", " + c.getInt(2));

    }

    c.close();

    }

    /**测试查询一条*/

    public void testQueryOneWithUriId() {

    ContentResolver resolver =this.getContext().getContentResolver();

    Uri uri =Uri.parse("content://com.itheima.sqlite.provider/3");//查询ID为3的记录

    Cursor c = resolver.query(uri, newString[] { "id", "name", "balance" }, null, null,null);

    if (c.moveToNext()) {

    System.out.println(c.getInt(0)+ ", " + c.getString(1) + ", " + c.getInt(2));

    }

    c.close();

    }

    /**测试获取内容提供者的返回类型*/

    public void testGetType() {

    ContentResolver resolver =this.getContext().getContentResolver();

    System.out.println(resolver.getType(Uri.parse("content://com.itheima.sqlite.provider/2")));

    System.out.println(resolver.getType(Uri.parse("content://com.itheima.sqlite.provider/person")));

    }

    }

    4、监听内容提供者的数据变化

    �在内容提供者中可以通知其他程序数据发生变化

    通过Context的getContentResolver()方法获取ContentResolver

    调用其notifyChange()方法发送数据修改通知,发送到系统的公共内存(消息信箱中)

    �在其他程序中可以通过ContentObserver监听数据变化

    通过Context的getContentResolver()方法获取ContentResolver

    调用其registerContentObserver()方法指定对某个Uri注册ContentObserver

    自定义ContentObserver,重写onChange()方法获取数据

    示例代码(发通知部分):

    public int delete(Uri uri, Stringselection, String[] selectionArgs) {

    SQLiteDatabase db =helper.getWritableDatabase();

    int delete =db.delete("person", selection, selectionArgs);

    // ==通过内容访问者对象ContentResolve发通知给所有的Observer ==

    getContext().getContentResolver().notifyChange(uri,null);

    db.close();

    returndelete;

    }

    }

    监听部分:

    //注册内容观察者事件

    private voidinitRegisterContentObserver() {

    Uri uri =Uri.parse("content://com.itheima.sqlite.provider");//监听的URI

    // ==第2个参数:true表示监听的uri的后代都可以监听到==

    getContentResolver().registerContentObserver(uri,true, new ContentObserver(new Handler()) {

    public voidonChange(boolean selfChange) {//接到通知就执行

    personList =personDao.queryAll();

    ((BaseAdapter)personListView.getAdapter()).notifyDataSetChanged();

    }

    });

    }

    5、区别Provider/Resolver/Observer

    1)ContentProvider:内容提供者

    把一个应用程序的私有数据(如数据库)信息暴露给别的应用程序,让别的应用程序可以访问;

    在数据库中有对应的增删改查的方法,如果要让别的应用程序访问,需要有一个路径uri:

    通过content://路径对外暴露,uri写法:content://主机名/表名

    2)ContentResolver:内容解析者

    根据内容提供者的路径,对数据进行操作(crud);

    3)ContentObserver:内容观察者

    可以理解成android系统包装好的回调,数据发送变化时,会执行回调中的方法;

    ContentResolver发送通知,ContentObserver监听通知;

    当A的数据发生变化的时候,A就会显示的通知一个内容观察者,不指定观察者,就会发消息给一个路径

    相关文章

      网友评论

          本文标题:从事Android以来的相关总结2-Android技能

          本文链接:https://www.haomeiwen.com/subject/svqbzttx.html