安卓组件自学

安卓开发

1.Activity

1.销毁程序时先销毁进入当前页面的那个activity,再销毁当前activity
2.创建流程
onCreat -> onStart -> onResume -> onPause -> onStop -> onDestory
onRestart被调用后跳转到onStart
3.四种模式:
在这里插入图片描述

2.Service

service生命周期
在这里插入图片描述

1.Service不是一个单独的进程,它和它的应用程序在同一个进程中
2.Service不是一个线程,这样就意味着我们应该避免在Service中进行耗时操作
3.当一个后台的任务,需要分成几个子任务,然后按先后顺序执行子任务 (简单的说就是异步操作),此时如果我们还是定义一个普通Service,然后在onStart方法中开辟线程,然后又要去控制线程,这样显得非常的繁琐; 此时应该自定义一个IntentService然后再onHandleIntent()方法中完成相关任务!
4.Activity与Service进行通信时,交流媒介便是Service中的onBind方法,返回我们自定义的Binder对象
流程:
(1).自定义Service中,自定义一个Binder类,然后将需要暴露的方法都写到该类中!
(2).Service类中,实例化这个自定义Binder类,然后重写onBind()方法,将这个Binder对象返回!
(3).Activity类中实例化一个ServiceConnection对象,重写onServiceConnected()方法,然后 获取Binder对象,然后调用相关方法即可!
5.定时任务处理流程
Step 1:获得Service: AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
Step 2:通过set方法设置定时任务 int anHour = 2 * 1000; long triggerAtTime = SystemClock.elapsedRealtime() + anHour; manager.set(AlarmManager.RTC_WAKEUP,triggerAtTime,pendingIntent);
Step 3:定义一个Service 在onStartCommand中开辟一条事务线程,用于处理一些定时逻辑
Step 4:定义一个Broadcast(广播),用于启动Service 最后别忘了,在AndroidManifest.xml中对这Service与Boradcast进行注册!
6.IBinder是Android给我们提供的一个进程间通信的一个接口,而我们一般是不直接实现这个接口的, 而是通过继承Binder类来实现进程间通信!是Android中实现IPC(进程间通信)的一种方式!

Binder机制

在这里插入图片描述
流程解析:
-> Client调用某个代理接口中的方法时,代理接口的方法会将Client传递的参数打包成Parcel对象;
-> 然后代理接口把该Parcel对象发送给内核中的Binder driver;;
-> 然后Server会读取Binder Driver中的请求数据,假如是发送给自己的,解包Parcel对象, 处理并将结果返回;
PS:代理接口中的定义的方法和Server中定义的方法是一一对应的, 另外,整个调用过程是一个同步的,即Server在处理时,Client会被Block(锁)住! 而这里说的代理接口的定义就是等下要说的AIDL(Android接口描述语言)!

Service绑定方法

startService进行绑定 在创建后只创建一个Service,完成后调用onStartCommand,在其他需要创建Service时只用再次调用onStartCommand,这个方法生成的Service和调用者无关,等到onDestory执行时才会销毁
bindService进行绑定 当第一次绑定时,系统会实例化一个对象,调用其的onCreat和onBind方法,然后调用者就可以用IBinder和Service进行通信了,此后如果再次使用bindService绑定Service,不会创建新的Service实例,直接把IBinder对像传给其他,解除绑定时,只需要调用unbindService,再所有的客户端都解除绑定时,才会调用onUbind和onDestory,当所有的客户端都解除绑定时,Service立即终止
先startService进行创建,再通过bindService进行绑定 其生命周期:onCreate( )->onStartCommand( )->onBind( )->onUnbind( )->onRebind( ),因为Service是通过startService进行创建的,所以在所有的客户端接触绑定后并不会进行销毁

方法解析

bindService(Intent Service,ServiceConnection conn,int flags)

service:通过该intent指定要启动的Service
conn:ServiceConnection对象,用户监听访问者与Service间的连接情况, 连接成功回调该对象中的onServiceConnected(ComponentName,IBinder)方法; 如果Service所在的宿主由于异常终止或者其他原因终止,导致Service与访问者间断开 连接时调用onServiceDisconnected(CompanentName)方法,主动通过unBindService() 方法断开并不会调用上述方法!
flags:指定绑定时是否自动创建Service(如果Service还未创建), 参数:0(不自动创建)BIND_AUTO_CREAT(自动创建)

设置定时任务:set(int type,long startTime,PendingIntent pi)

①type: 有五个可选值:
AlarmManager.ELAPSED_REALTIME: 闹钟在手机睡眠状态下不可用,该状态下闹钟使用相对时间(相对于系统启动开始),状态值为3;
AlarmManager.ELAPSED_REALTIME_WAKEUP 闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟也使用相对时间,状态值为2;
AlarmManager.RTC 闹钟在睡眠状态下不可用,该状态下闹钟使用绝对时间,即当前系统时间,状态值为1;
AlarmManager.RTC_WAKEUP 表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟使用绝对时间,状态值为0;
AlarmManager.POWER_OFF_WAKEUP 表示闹钟在手机关机状态下也能正常进行提示功能,所以是5个状态中用的最多的状态之一, 该状态下闹钟也是用绝对时间,状态值为4;不过本状态好像受SDK版本影响,某些版本并不支持;
第一个参数决定第二个参数的类型,如果是REALTIME的话就用: SystemClock.elapsedRealtime( )方法可以获得系统开机到现在经历的毫秒数 如果是RTC的就用:System.currentTimeMillis()可获得从1970.1.1 0点到 现在做经历的毫秒数
②startTime: 闹钟的第一次执行时间,以毫秒为单位,可以自定义时间,不过一般使用当前时间。 需要注意的是,本属性与第一个属性(type)密切相关,如果第一个参数对应的闹钟 使用的是相对时间(ELAPSED_REALTIME和ELAPSED_REALTIME_WAKEUP),那么本属 性就得使用相对时间(相对于系统启动时间来说),比如当前时间就表示为: SystemClock.elapsedRealtime();如果第一个参数对应的闹钟使用的是绝对时间 (RTC、RTC_WAKEUP、POWER_OFF_WAKEUP),那么本属性就得使用绝对时间, 比如当前时间就表示为:System.currentTimeMillis()。
③PendingIntent: 绑定了闹钟的执行动作,比如发送一个广播、给出提示等等。PendingIntent 是Intent的封装类。
需要注意的是,如果是通过启动服务来实现闹钟提示的话, PendingIntent对象的获取就应该采用Pending.getService (Context c,int i,Intent intent,int j)方法;
如果是通过广播来实现闹钟提示的话, PendingIntent对象的获取就应该采用 PendingIntent.getBroadcast (Context c,int i,Intent intent,int j)方法;
如果是采用Activity的方式来实现闹钟提示的话,PendingIntent对象的获取 就应该采用 PendingIntent.getActivity(Context c,int i,Intent intent,int j) 方法。
如果这三种方法错用了的话,虽然不会报错,但是看不到闹钟提示效果。

广播

动态注册

在java代码中指定IntentFilter,然后添加不同的Action即可,想监听什么广播就写什么action,动态注册的广播,一定要调用unregisterReceiver让广播取消注册,需要程序启动才能接受广播

静态注册

在AndroidManifest中制定<IntentReceiver>就可以让程序在未启动的情况下接受广播

注意

从Android 8.0(API级别26)开始,该系统对声明清单的接收者施加了额外的限制。
如果你的应用目标是Android 8.0或更高版本,你不能使用清单为大多数隐式广播(不是专门针对你的应用的广播)声明接收器。当用户正在使用你的应用程序时,你仍然可以使用上下文注册的接收器。
即定义的静态广播必须指定范围(应用),类似于生活中广播要在指定频道才能收到。

内容传播者ContentProvider

在这里插入图片描述

自定义ContentProvider流程

在这里插入图片描述

Intent

类别

显式:通过组件名指定启动的目标组件,比如startActivity(new Intent(A.this,B.class)),每次启动的组件只有一个
隐式:不指定组件名,而指定Intent的Action,Data,或Category,当我们启动组件时, 会去匹配AndroidManifest.xml相关组件的Intent-filter,逐一匹配出满足属性的组件,当不止一个满足时, 会弹出一个让我们选择启动哪个的对话框~
在这里插入图片描述

七个属性

ComponentName(组件名称)
在这里插入图片描述
Action(动作)
在这里插入图片描述Category(类别)
在这里插入图片描述
Data(数据),Type(MIME类型)

在这里插入图片描述
Extras(额外)
在这里插入图片描述
Flags(标记)
在这里插入图片描述

传递数据

1.简单数据
发送方
先实例化一个intent对象,在实例化一个Bundle对象,通过Bundle对象的putString、putInt等方法将要传递的信息放入Bundle对象中,再通过intent的putExtras(Bundle对象)传入到接受对象中
接受方
通过getIntent获取Intent对象,完成后通过Intent的getExtras获取Bundle对象,通过bundle对象的getInt、getString等方法获取传递过来的值
2.数组
发送方
先实例化一个intent对象,在实例化一个Bundle对象,通过Bundle对象的putStringArrary()写入传入的键和数组值到Bundle对象中,再通过intent的putExtras(Bundle对象)传入到接受对象中
接收方
通过getIntent获取Intent对象,完成后通过Intent的getExtras获取Bundle对象,通过bundle对象的getStringArrary(”键“)获取传递过来的值
3.集合
List<基本数据类型或String>
发送方
intent.putStringArraryListExtra(键,值)
intent.putIntegerArrayListExtra(键,值)
接受方
intent.getStringArraryListExtra(键,值)
intent.getIntegerArrayListExtra(键,值)
List<Object>
发送方
intent.putExtras(key,(Serializable)list)
读取方
(List<Object>) getIntent.getSerializable(key)
Map<String,Object>
在Map外面套一个List
4.传递对象
将对象转换成Json字符串
发送方
intent.putExtra(,new Gson.toJson(要传递的对象))
接受方
通过getStringExtra()进行获取,在使用Gson的formJson方法进行获取
使用Serializable,Parcelable序列化对象
(1)使用Serializable实现
①业务Bean实现:Serializable接口,写上getter和setter方法
②Intent通过调用putExtra(String name, Serializable value)传入对象实例 当然对象有多个的话多个的话,我们也可以先Bundle.putSerializable(x,x);
③将跳转的Activity调用getSerializableExtra()方法获得对象实例: eg:Product pd = (Product) getIntent().getSerializableExtra(“Product”);
④调用对象get方法获得相应参数
(2)使用Parcelable实现
①业务Bean继承Parcelable接口,重写writeToParcel方法,将你的对象序列化为一个Parcel对象;
②重写describeContents方法,内容接口描述,默认返回0就可以
③实例化静态内部对象CREATOR实现接口Parcelable.Creator
④同样式通过Intent的putExtra()方法传入对象实例,当然多个对象的话,我们可以先 放到Bundle里Bundle.putParcelable(x,x),再Intent.putExtras()即可
解释:通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射成你的对象。也可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面, 在通过createFromParcel从流里读取对象,只不过这个过程需要你来实现,因此写的 顺序和读的顺序必须一致。

Fragment

会收到宿主Activity的影响,宿主Activity被销毁时,它也将会销毁

Fragment的生命周期

在这里插入图片描述
注意

1.Fragment需要嵌套在Activity中使用,当然也可以嵌套到另外一个Fragment中,但这个被嵌套 的Fragment也是需要嵌套在Activity中的,间接地说,Fragment还是需要嵌套在Activity中!! 受寄主Activity的生命周期影响,当然他也有自己的生命周期!另外不建议在Fragment里面嵌套Fragment因为嵌套在里面的Fragment生命周期不可控!!!
2.Fragment的生命周期和Activity有点类似:三种状态:
Resumed:在允许中的Fragment可见
Paused:所在Activity可见,但是得不到焦点
Stoped: ①调用addToBackStack(),Fragment被添加到Bcak栈 ②该Activity转向后台,或者该Fragment被替换/删除
ps:停止状态的fragment仍然活着(所有状态和成员信息被系统保持着),然而,它对用户不再可见,并且如果activity被干掉,他也会被干掉
一些关于生命周期变化信息:
①Activity加载Fragment的时候,依次调用下面的方法: onAttach -> onCreate -> onCreateView -> onActivityCreated -> onStart ->onResume
②当我们弄出一个悬浮的对话框风格的Activity,或者其他,就是让Fragment所在的Activity可见,但不获得焦点 onPause
③当对话框关闭,Activity又获得了焦点: onResume
④当我们替换Fragment,并调用addToBackStack()将他添加到Back栈中 onPause -> onStop -> onDestoryView !!注意,此时的Fragment还没有被销毁哦!!!
⑤当我们按下键盘的回退键,Fragment会再次显示出来: onCreateView -> onActivityCreated -> onStart -> onResume
⑥如果我们替换后,在事务commit之前没有调用addToBackStack()方法将 Fragment添加到back栈中的话;又或者退出了Activity的话,那么Fragment将会被完全结束, Fragment会进入销毁状态 onPause -> onStop -> onDestoryView -> onDestory -> onDetach

创建一个Fragment

静态加载一个Fragment
实现流程
在这里插入图片描述
动态加载一个Fragment
在这里插入图片描述

管理与事务

在这里插入图片描述

Fragment与Activity的交互

在这里插入图片描述
1.组件获取

Fragment获取Activity中的组件:getActivity().findViewByid()
Activity获得Fragment中的组件:getFragmentManager.findFragmentByid()

2.数据传递

(1).Activity传递数据给Fragment:
在Activity中创建Bundle数据包,调用Fragment实例的setArguments(bundle)从而将Bundle数据包传给Fragment,然后Fragment中调用getArguments获取Bundle对象,然后进行解析就行了
(2).Fragment传递数据给Activity
在Fragment中定义一个内部回调接口,再让包含该Fragment的Activity实现该回调接口,Fragment就可以通过接口传数据了

3.Fragment与Fragment之间的数据互传

其实这很简单,找到要接受数据的fragment对象,直接调用setArguments传数据进去就可以了 通常的话是replace时,即fragment跳转的时候传数据的,那么只需要在初始化要跳转的Fragment 后调用他的setArguments方法传入数据即可!
如果是两个Fragment需要即时传数据,而非跳转的话,就需要先在Activity获得f1传过来的数据, 再传到f2了,就是以Activity为媒介~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值