Android四大组件-BroadcastReceiver、ContentProvider、Service

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wzhworld/article/details/83472795

目录

一、BroadcastReceiver

1、定义

2、作用

3、生命周期

4、广播注册方式

动态注册

静态注册

5、广播类型

普通广播:即发出广播后所有接收者都能收

有序广播:按照广播的优先级接受,broadcastReceiver可以在onReceive中使用abortBroastcast()终止广播下传

系统广播:系统的广播,如电量、锁屏等

本地广播:只在本应用内接收得到,需将exported置为false

粘留广播:Api21后已经废弃了,其作用是可以在发出广播之后注册的接收器仍然可以接收到广播

6、返回值

二、ContentProvider

1、定义

2、URI

3、详细使用待续

三、Service

1、定义

2、生命周期

3、PS

4、Service类型

5、IntentService


有兴趣可以看前面的Activity介绍:https://blog.csdn.net/wzhworld/article/details/83443862

一、BroadcastReceiver

详见:https://blog.csdn.net/carson_ho/article/details/52973504

1、定义

  • BroadcastReceiver,本质上是一个全局的监听器,属于Android四大组件之一。主要扮演角色是发送者以及接收者

2、作用

  • 广播主要可以用于不同组件、App之间的通信

3、生命周期

  • onReceive进行接收广播之后的广播处理
public class mBroadcastReceiver extends BroadcastReceiver {

  //接收到广播后自动调用该方法
  @Override
  public void onReceive(Context context, Intent intent) {
   //写入接收广播后的操作
    }
}

4、广播注册方式

  • 动态注册

@Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

    //实例化BroadcastReceiver子类 &  IntentFilter
     mBroadcastReceiver mBroadcastReceiver = new mBroadcastReceiver();
     IntentFilter intentFilter = new IntentFilter();

    //设置接收广播的类型
     intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);

    //调用Context的registerReceiver()方法进行动态注册
     registerReceiver(mBroadcastReceiver, intentFilter);
 }


//注册广播后,要在相应位置记得销毁广播
//即在onDestroy()中unregisterReceiver(mBroadcastReceiver)
 @Override
 protected void onDestroy() {
     super.onDestroy();
      //销毁在onCreate()方法中的广播
     unregisterReceiver(mBroadcastReceiver);
     }
}
  • 静态注册

    • 首先在manifest中注册
      <receiver 
          //此广播接收者类是MyBroadcastReceiver
          android:name=".MyBroadcastReceiver" >
          //用于接收网络状态改变时发出的广播
          <intent-filter>
              <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
          </intent-filter>
      </receiver>
      

      后在自定义的BroadcastReceiver的onReceive进行处理即可,注意静态注册的广播需要进行一定的处理,因为在Android中为了防止恶意攻击之类,不可以随便定义静态注册,所以简单的上述代码的注册可能会接收不到广播,可以加上包名的设定,详见https://blog.csdn.net/u011386173/article/details/82889275

      intent.setPackage(getPackageName());

5、广播类型

  • 普通广播:即发出广播后所有接收者都能收

<receiver 
    //此广播接收者类是MyBroadcastReceiver
    android:name=".MyBroadcastReceiver" >
    //用于接收网络状态改变时发出的广播
    <intent-filter>
        <action android:name="ANY_ACTION" />
    </intent-filter>
</receiver>
Intent intent =  new Intent();
intent.setAction("ANY_ACTION");
sendBroadcase(intent);
  • 有序广播:按照广播的优先级接受,broadcastReceiver可以在onReceive中使用abortBroastcast()终止广播下传

sendOrderedBroadcast(intent);
abortBroastcast();
  • 系统广播:系统的广播,如电量、锁屏等

    •  
  • 本地广播:只在本应用内接收得到,需将exported置为false

  • //注册应用内广播接收器
    //步骤1:实例化BroadcastReceiver子类 & IntentFilter mBroadcastReceiver 
    myBroadcastReceiver = new MyBroadcastReceiver(); 
    IntentFilter intentFilter = new IntentFilter(); 
    
    //步骤2:实例化LocalBroadcastManager的实例
    localBroadcastManager = LocalBroadcastManager.getInstance(this);
    
    //步骤3:设置接收广播的类型 
    intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
    
    //步骤4:调用LocalBroadcastManager单一实例的registerReceiver()方法进行动态注册 
    localBroadcastManager.registerReceiver(myBroadcastReceiver , intentFilter);
    
    //取消注册应用内广播接收器
    localBroadcastManager.unregisterReceiver(myBroadcastReceiver );
    
    //发送应用内广播
    Intent intent = new Intent();
    intent.setAction(BROADCAST_ACTION);
    localBroadcastManager.sendBroadcast(intent);
    

    粘留广播:Api21后已经废弃了,其作用是可以在发出广播之后注册的接收器仍然可以接收到广播

6、返回值

  • 不同注册方式的onReceive中Context返回值是不一样的

    • 对于静态注册(全局+应用内广播),回调onReceive(context, intent)中的context返回值是:ReceiverRestrictedContext;

    • 对于全局广播的动态注册,回调onReceive(context, intent)中的context返回值是:Activity Context;

    • 对于应用内广播的动态注册(LocalBroadcastManager方式),回调onReceive(context, intent)中的context返回值是:Application Context。

    • 对于应用内广播的动态注册(非LocalBroadcastManager方式),回调onReceive(context, intent)中的context返回值是:Activity Context;

二、ContentProvider

1、定义

内容提供者,实现应用内、应用间建数据共享https://blog.csdn.net/carson_ho/article/details/76101093

2、URI

3、使用

  • 自定义的ContentProvider类:ContentProvider的数据一般是以"数据库"或"网络数据"的方式存储的。如果是数据库,则需要实现SQLiteOpenHelper类。通过SQLiteOpenHelper类新建/管理数据库。
  • 我们需要以继承ContentProvider的方式自定义ContentProvider时,需要实现query(), insert(), update(), delete(), getType(), onCreate()这六个函数。
  1. 创建表格
    // 创建表格的SQL语句
    private static final String SQL_CREATE_ENTRIES =
        "CREATE TABLE " + Entry.TABLE_NAME + " (" +
        Entry._ID + " INTEGER PRIMARY KEY," +
        Entry.NAME + " TEXT NOT NULL, " +
        Entry.BIRTH_DAY + " TEXT, " +
        Entry.EMAIL + " TEXT, " +
        Entry.GENDER + " INTEGER " +
        " )";
    
    ...
    
    private class DBLiteHelper extends SQLiteOpenHelper {
        public static final int DATABASE_VERSION = 1;
        public static final String DATABASE_NAME = "MyProvider.db";
    
        public DBLiteHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(SQL_CREATE_ENTRIES);
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        }
    }

    在创建时execSQL语句创建数据库

  2. 注册Uri
    // Uri的authority
    public static final String AUTHORITY = "com.skw.myprovider";
    // Uri的path
    public static final String PATH = "table01";
    // UriMatcher中URI对应的序号
    public static final int ITEM_ALL = 1;
    public static final int ITEM_ID  = 2;
    
    private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
    static {
        URI_MATCHER.addURI(AUTHORITY, PATH, ITEM_ALL);
        URI_MATCHER.addURI(AUTHORITY, PATH+"/#", ITEM_ID);
    }

    注册Uri的目的是为了添加侦听,将Uri注册到UriMatcher中,AUTHORITY需要与manifest中的android:authorities相同一致

  3. delete()、insert()、update()、query()这几个方法都是相同类似的操作,如果底层使用的是Sqlite,那么增删查改其实就是对于这四个的封装,到这里不禁就要思考问啥不直接使用sqlite要加一层ContentProvider这么麻烦了。设想一下,假如当需要数据从网络取而不是从数据库取得,那么底层的取数据操作我们又要重新实现一遍,这很不合理,通过CP的提供接口而不关心底层实现,当需要变动了无需改动过多。
  4. Manifest注册
    <provider android:name=".MyProvider"
              android:authorities="上述定义的协议"
    />
  5. 对ContentProvider进行操作时,我们使用的是ContentResolver而不是CP,目的是为了统一封装接口对应用内、应用外使用
    ContentResolver cr = new ContentResolver();
    cr.insert(...);
    cr.query(...);
    cr.delete(...);
    cr.query(...);

    详细使用可见https://blog.csdn.net/carson_ho/article/details/76101093

  6. 跨应用使用后续待修改,与权限应用相关

三、Service

1、定义

运行在后台不直接与用户交互的,比如可开启线程作网络操作等

2、生命周期

https://blog.csdn.net/carson_ho/article/details/53160137

此处应该注意的是startService与bindService的区别,start后Service无法控制。而bindService启动后可通信,通过Binder

3、PS

  • startService()和stopService()只能开启和关闭Service,无法操作Service;

  • bindService()和unbindService()可以操作Service

  • startService开启的Service,调用者退出后Service仍然存在;

  • BindService开启的Service,调用者退出后,Service随着调用者销毁

4、Service类型

可见https://www.jianshu.com/p/e04c4239b07e

  • 本地服务:即正常使用只在主线程运作
  • 远程服务:跑在独立进程,需使用AIDL进行IPC操作
  • 前台服务:结合Notification显示在通知栏的
  • 后台服务:处于后台如更新天气此类
  • 详见上述的网址,讲得比较详细

5、IntentService

待后续补充,这个Service通常是用来做耗时的操作,其底层实现是通过Handler、Thread实现耗时,在onHandleIntent接收到Intent识别判断类型后可以操作

猜你喜欢

转载自blog.csdn.net/wzhworld/article/details/83472795