上一篇文章的传送门:Android常见问题总结(一)
广播的两种注册方法
Android四大组件之一的broadcast(广播)拥有两种不同的注册方法:静态注册与动态注册
静态注册
广播静态注册指把广播相应的信息写在AndroidManifest.xml中,例子如下:
1 | <receiver android:name=".StaticReceiver"> |
静态广播的好处在于:不需程序启动即可接收,可用作自动启动程序
动态注册
广播动态注册指在程序中调用registerReceiver方法来注册广播,例子如下:
1 | IntentFilter filter = new IntentFilter(); |
动态广播的好处在于:程序适应系统变化做操作,但在程序运行状态才能接收到
Intent的使用
Intent即意图,是Android中连接四大组件的枢纽,Android中的Activity、Service和BroadcastReceiver都依靠Intent来启动
Intent对象的属性大致包含七种,分别是Component、Action、Category、Data、Type、Extra、Flag
Component
Component用于明确指定需要启动的目标组件,使用方法如下:
1 | Intent intent = new Intent(); |
指定Component属性的Intent已经明确了它将要启动的组件,因此这种Intent也被称为显示Intent,没有指定Component属性的Intent被称为隐试Intent
Action、Category
Action代表Intent所要完成的一个抽象“动作”,而Category则用于为Action增加额外的附加类别信息,它们的使用方法如下:
1 | Intent intent = new Intent(); |
值得注意的是Action属性是唯一的,但Category属性可以有多个。通常设置了Action和Category来启动组件的Intent就不指定Component属性了,因此这种Intent被称为隐试Intent
Data、Type
Data属性接受一个Uri对象,Data属性通常用于向Action属性提供操作的数据。Type属性用于指定该Data属性所指定Uri对应的MIME类型。它们的使用方法如下:
1 | Intent intent = new Intent(); |
值得注意的是Data属性和Type属性会互相覆盖,如果需要同时设置Data属性和Type属性需要使用setDataAndType
Extra
Intent的Extra属性用于进行数据交换,Intent的Extra属性值应该是一个Bundle对象(一个类似Map的对象,可以存入多个键值对,但存入的对象必须是基本类型或可序列化的),用法如下:
1 | Intent intent = new Intent(); |
Flag
Intent的Flag属性用于为该Intent添加一些额外的控制旗标,Intent可调用addFlags方法来添加控制旗标
ContentProvider使用方法
为了在应用程序之间交换数据,Android提供了ContentProvider。当一个应用程序需要把自己的数据暴露给其他程序使用时,该应用程序就可以通过ContentProvider来实现,而其他程序则使用ContentResolver来操作ContentProvider暴露的数据。
实现ContentProvider的Java代码如下:
1 | public class MyProvider extends ContentProvider { |
当我们实现了自己的ContentProvider后,还需要去AndroidManifest.xml中注册才行:
1 | <provider |
配置ContentProvider时我们需要设置如下属性:
- name:类名
- authorities:为ContentProvider指定一个对应的Uri,其他程序通过这个Uri来找到该ContentProvider
- exported:允许ContentProvider被其他应用调用
当其他应用需要访问我们提供的ContentProvider的使用,只需使用ContentResolver并传入相应的Uri即可:
1 | public class MyActivity extends Activity { |
除此之外,我们还可以使用ContentObserver来为ContentProvider添加观察者。我们在其他程序的ContentResolver中注册ContentObserver,当ContentProvider发生改变时,我们在数据改动的使用调用:
1 | getContext().getContentResolver().notifyChange(uri, null); |
那么此时ContentObserver中的onChange回调方法就会被调用,我们就可以简单地监听ContentProvider的数据改变了
Thread、AsycTask、IntentService的使用场景与特点
Thread、AsyncTask和IntentService都与多线程有关,当我们在Android中涉及并发编程时(进行网络请求、加载较大的文件等操作)就需要使用
Thread
Java中的子线程,可以通过传入Runnable接口或继承Thread重写run方法新建
AsyncTask
由Java线程池改造的异步任务工具
IntentService
Android四大组件之一的Service默认是在主线程中运行的,IntentService是Service的子类,有如下特点:
- IntentService会创建单独的worker线程来处理所有的Intent请求
- 当所有请求处理完成后,IntentService会自动停止
- 为Service的onBind方法提供了默认实现,返回null
- 为Service的onStartCommand方法提供了默认实现,把请求Intent添加到队列中
实现IntentService的例子如下:
1 | public class MyIntentService extends IntentService { |
我们只需重写onHandleIntent方法即可,该方法的代码会在一个子线程中运行
五种Layout各自特点
FrameLayout
FrameLayout即单帧布局,在该布局中的所有空间都会被置于布局的左上角
LinearLayout
LinearLayout即线性布局,使用该布局必须为其指定orientation属性(排列方向属性,可以设置为水平或垂直的),其中的空间就会根据设置的属性呈水平或垂直排列
AbsoluteLayout
AbsoluteLayout即绝对布局,对布局中的控件我们使用x,y坐标值进行定位
RelativeLayout
RelativeLayout即相对布局,在其中的控件可以相对于父布局或布局中别的控件的位置进行定位布局
TableLayout
TableLayout即表格布局,TableLayout中的每一行的控件由TableRow包含,最终的布局效果会呈现成表格状