评论

收藏

[Android] Android学习笔记——四大组件

移动开发 移动开发 发布于:2022-07-27 17:36 | 阅读数:582 | 评论:0

四大组件
Activity
实现步骤

  • 继承 Activity 或其子类,实现以下方法:
    //第一次创建时回调
    protected void onCreate(Bundle savedInstanceState);
    //启动时回调
    protected void onStart();
    //再次启动时回调
    protected void onRestart() ;
    //回到前台时回调
    protected void onResume();
    //转入后台但依然可见时回调
    protected void onPause() ;
    //转入后台完全不可见时回调
    protected void onStop();
    //被系统销毁时回调
    protected void onDestroy();
  • 在 AndroidMainfest.xml 文件中配置
  • 启动,有以下两种方式:
    //启动其他Activity
    startActivity(Intent intent);
    //启动其让Activity并返回请求码
    startActivityForResult(Intent intent,int requestCode);
  • 停止,有以下两种方式:
    //结束当前Activity
    finish();
    //结束当前Activity并返回状态码
    finish(Intent intent,int requestCode);
IBindle与Activity之间的通信
IBindle 是一个简单的数据携带包,用于实现 Activity 之间的数据交换。Intent 提供了 putExtras() 和 getExtras() 方法,这些方法实质是存取 Intent 所携带的 IBindle 中的数据。
Intent 提供的多个重载方法携带额外数据:
//向Intent中存放数据包
putExtras(Bundle data);
//取出Intent中存放的数据包
getExtras(Bundle data);
//向Intent中以k-v形式存放数据包
putExtra(String name,String value);
//根据k取出指定类型的值
getXxxExtra(String name);
Bundle包含的多个方法来存入数据:
//向Bundle中存放数据
putXxx(String key,Xxx data);
//向Bundle中存放一个可序列化对象
putSerialzable(String key,Serialzable data);
生命周期
运行状态:当前 Activity 位于前台,用户可见,可以获得焦点;
暂停状态:其他 Activity  位于前台,该 Activity 依然可见,但无法获得焦点;
停止状态:该 Activity 不可见,无法获得焦点;
销毁状态:该 Activity 结束或 Activity 所在进程被结束。
四种加载模式
standard:每次启动目标 Activity 时,总会为目标 Activity 创建一个新实例,并添加到原有的 Task 中。
singleTop:当将要启动的目标 Activity 位于 Task 栈顶中,系统直接服用已有的 Activity 实例。
singleTask:包括以下三种情况

  • 启动目标 Activity 不存在,创建新实例并加入到 Task 栈顶中;
  • 启动目标 Activity 存在且位于 Task 栈顶,直接复用已有 Activity 实例;
  • 启动目标 Activity 存在但不在 Task 栈顶,将位于目标 Activity 之上的实例移除 Task。
singleInstance:包括以下两种情况:

  • 启动目标 Activity 不存在,先创建一个 Task,然后创建目标 Activity 实例并添加到 Task 中;
  • 启动目标 Activity 存在,将该 Activity 所在 Task 转到前台,使该 Activity 显示出来。
ContentProvide
ContentProvide 是不同应用程序之间进行交换的标准 API,以某种 Uri 的形式对外提供数据,允许其他应用访问或修改数据。
实现步骤

  • 继承 ContentProvider,实现以下方法:
    //当其他程序第一次访问该ContentProvider时,该ContentProvider被创建出来并立即回调onCreate()
    public boolean onCreate();
    //根据Uri查询selection条件所匹配的全部记录,projection指的是列名列表,表明只选择出指定的数据列
    public Cursor query(Uri uri, String[] projection,String selection,String[] selectionArgs,String sortOrder);
    //用于返回当前Uri所代表的MIME类型
    //若Uri对应数据包含多条记录,该MIME类型字符串应以vnd.android.cursor.dir/开头
    //若Uri对应数据包含一条记录,该MIME类型字符串应以vnd.android.cursor.item/开头
    public String getType(Uri uri);
    //根据Uri插入values对应的数据
    public Uri insert(Uri uri, ContentValues values);
    //根据Uri删除selection所匹配的全部记录
    public int delete(Uri uri, String selection,String[] selectionArgs);
    //根据Uri修改selection条件所匹配的全部记录
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs);
  • 向 AndroidMainfest.xml 文件中注册该 ContentProvider,并为它绑定一个 Uri
Uri类似于互联网中的URL,URL由协议、域名、网站资源三个部分组成,Uri可以分为以下三部分
Content://:暴露和访问ContentProvider的协议默认为content://
org.crazyit.providers.dictprovider:这部分是ContentProvider的authorities,用于指定要访问的ContentProvider
words:资源部分
Uri基本遵循了RESTful风格
ContentResolver
ContentProvider 相当于一个网站,它的作用是暴露可供操作的数据,其他程序则通过 ContentResolve r来操作 ContentProvider 所暴露的数据。ContentResolver 相当于 HttpClient.
Context 提供了以下方法来获取 ContentResolver 对象:
//获取应用的默认ContentResolver
getContentResolver();
//向Uri对应的ContentProvider
insert(Uri url,ContentValues values);
//删除Uri对应的ContentProvider中where条件匹配数据
delete(Uri url,String where,String[] selectionArgs);
//更新Uri对应的ContentProvider中where条件匹配数据
update(Uri url,String where,String[] selectionArgs);
//查询Uri对应的ContentProvider中where条件匹配数据
query(Uri url,String[] projection,String selection,String[] selectionArgs,String sortOrder)
ContentProvider 一般为单实例模式,多个程序通过 ContentResolver 操作 ContentProvider 提供数据时,会委托给同一个 ContentProvider
Uri 参数判断
为了确定 ContentProvider 能够处理 Uri,以及确定每个方法中 Uri 参数所操作的数据, Android 提供了 UriMatch、ContentUris 工具类。
UriMatcher 工具类
//向UriMatcher对象注册Uri
void addURL(String authority,String path,int code);
//根据前面注册的Uri来判断Uri对应的标识,若无法匹配则返回-1
int match(Uri uri);
ContentUris 工具类
//用于为路径添加ID部分
withAppendId(Uri contentUri, long id)
//用于指定Uri中解析出包含ID值
parseId(Uri contentUri);
系统的ContentProvider
Uri说明ContactsContract.Contacts.CONTENT_URL管理联系人的UriContactsContract.CommonDataKinds.Phone.CONTENT_URL管理联系人电话的UriContactsContract.CommonDataKinds.Email.CONTENT_URL管理联系人E-mail的UriMediaStore.Audio.Media.EXTERNAL_CONTENT_URL存储在手机外部存储器上的音频文件内容的UriMediaStore.Audio.Media.INTERNAL_CONTENT_URL存储在手机内部存储器上的音频文件内容的UriMediaStore.Images.Media.EXTERNAL_CONTENT_URL存储在手机外部存储器上的图片文件内容的UriMediaStore.Video.Media.INTERNAL_CONTENT_URL存储在手机内部存储器上的视频文件内容的UriMediaStore.Video.Media.EXTERNAL_CONTENT_URL存储在手机外部存储器上的视频文件内容的UriService
实现步骤

  • 继承 Service 重写回调方法
  • 在 Androidmainfest.xml 文件中配置该 Service
  • 运行 Service,包括以下两种方法:

    • Context 的 startService() 方法,该方法启动 Service 与启动者不建立连接关系,启动者退出 Service 保持运行。
    • Centext 的 bindService() 方法,该方法启动 Service 与启动者绑定在一起,启动者退出 Service 也退出。
    //创建启动Service的Intent
    Intent intent = new Intent(this, MusicService.class);
    //启动后台
    startService(intent);
    //关闭后台
    stopService(intent);
创建显式 Intents :
通过 Context、目标 Service 类创建显式 Intent
通过package、action 属性创建显式 Intent
绑定本地 Service 并与之通信
当 Service 与访问者 需要进行方法调用或交换数据时,应使用 bindService() 和 unbindService() 启动和关闭 Service。
/**
* Service: 通过Intent指定需要启动的Service
* Conn: 用于监听访问者与Service之间的连接情况. 
*    访问者与Service连接成功时将回调该ServiceConnection的onServiceConnected(ComponentName name,IBinder service)方法
*    访问者与Service连接异常时将回调该ServiceConnection的onServiceDisconnected(ComponentName name,IBinder service)方法
* flags: 绑定时是否自动创建Service,参数可为0(不自动创建)或BIND_AUTO_CREATE(自动创建)
* */
public boolean bindService(Intent service, ServiceConnection conn,int flags);
ServiceConnection 对象的 onServiceConnected(ComponentName name,IBinder service) 有一个 IBind(Intent intent) 对象,该对象可实现与绑定 Service 之间的通信。
开发 Service 类时,该 Service 类必须提供一个 IBinder onBind(Intent intent) 方法。实际开发时通常会采用继承 Binder 的方式实现 IBinder 对象。
生命周期
public class MusicService extends Service {
   //被创建时回调
  @Override
  public void onCreate() {
    super.onCreate();
  }
  //被绑定时回调
  @Override
  public IBinder onBind(Intent intent) {
    return null;
  }
  //被启动时回调
  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    return super.onStartCommand(intent, flags, startId);
  }
//被取消绑定时回调
  @Override
  public boolean onUnbind(Intent intent) {
    return super.onUnbind(intent);
  }
//被停止时回调
  @Override
  public void onDestroy() {
    super.onDestroy();
  }
}
IntentService
Service 与它所在的应用位于同一进程中,因此不应该在 Service 中直接处理耗时操作。
IntentService 具有如下特征:

  • IntentService 会创建独立线程处理 onHandleIntent() 方法实现的代码,开发者无需处理多线程问题。
  • 当所有请求处理完成后,IntentService 会自动停止,因此无需调用 stopSelf() 方法来停止 Service。
  • 为 Service 的 onBind() 方法提供了默认实现,默认返回为null.
  • 为 Service 的 onStartCommand() 方法提供了默认实现,该实现会自动将请求 Intent 加入队列中。
在使用扩展 IntentService 实现 Service 无须重写 onBind()、onStartCommand() 方法,只要重写 onHandleIntent() 方法即可。
BroadcastReceiver
broadcastReceiver 本质上是一个全局监听器,用于监听系统全局的广播消息。
启动步骤

  • 创建需启动的 BroadcastReceiver 的 Intent
  • 调用 Context 的 sendBroadcast() 或 sendOrderBroadcast() 方法启动指定的 BroadcastReceiver
    //创建Intent
    Intent intent = new Intent();
    //设置action属性
    intent.setAction("org.crazyit.action.CRAZY_BROADCAST");
    intent.setPackage("org.crazyit.broadcast");
    intent.putExtra("msg","简单的消息");
    //发送广播
    sendBroadcast(intent);
实现方式

  • 继承 BroadcastReceiver 重写 onReceive(Context context, Intent inten) 方法
  • 指定该 BroadcastReceiver 能匹配的 Intent,有以下两种方式:

    • 代码中使用 BroadcastReceiver 的 Context 的 registerReceiver(BroadcastReceiver receiver,IntentFilter filter)
    IntentFilter filter = new IntentFilter("android.provider.Telephoy.SMS_RECEIVED");
    IncomingSMSReceiver receiver = new IncomingSMSReceiver();
    registerReceiver(receiver ,filter);

    • 在 AndroidMainfest.xml 文件中配置
    <receiver android:name=".IncomingSMSReceiver">
    <intent-filter>
    <action android:name = "android.provider.Telephony.SMS_RECEIVERD"/>
    </intent-filter>
    </receiver>
    在实践过程中,发现 Receiver 只有放在项目主目录下才能被读取注册


   
   
   
                        

关注下面的标签,发现更多相似文章