注0:本文整理于 6 月 12 日,端午节后。
注1:回家跟家里商量了一下,反而好像,更加的迷茫了的说。
- Android 组件硬知识点
概述
组件即为可视的组件,甚至可以说一切可重用的 API 都能成为组件
重点在于代码的重用和组件的运用
组件的属性
android:id 属性不一定是必须的。android:id 只有两个作用:Java 代码引用和相对布局确定
android:padding 设置组件内容距离边缘。android:margin 用于组件组件之间间隔,或距离父组件边缘的距离。
android:grivaty 设置组件内容相对组件的位置。android:layout_grivaty 用于设置当前组件相对于父组件的位置。
android:weight 设置占比。使用的时候记得把相对的 layout_width 或 layout_height 设置为 0dp
文本组件
TextView 富文本信息
- 使用富文本标签。Html.fromHtml 方法将这些文本转换成 CharSequence 对象,然后传入 TextView.setText() 中。
图文混排时使用 <img> 标签需要实现 ImageGetter 接口,通过 ImageGetter.getDrawable 返回图像资源的 Drawable 对象
- 使用 WebView 组件显示 HTML 界面
- 继承 View 类,覆盖 onDraw 方法直接绘制
- 显示图像使用 ImageSpan 对象,Bitmap 传入之后通过 SpannableString 对象封装 ImageSpan,最后把 SpannableString 传入 setText 方法。
TextView 插入 URL 、Email 等特殊信息,并能实现点击的用法。
使用 android.text.style.ClickableSpan 自定义单击 URL 的动作。方法是创建 ClickableSpan 对象,在其 onClick 方法中编写代码。
输入词语,数据库比对联想使用 AutoCompleteTextView 组件,重写 TextWatcher.afterTextChanged 方法,查询之后更新 Adapter 对象。
按钮组件
按钮上显示图像的方法
- 使用 drawableXxx 将图像显示在文字的周围
- 使用 ImageSpan 封装 Bitmap ,使用 SpannableString.setSpan 方法设置 ImageSpan 对象,最后传入 Button.setText 或 append 方法
ImageButton 使用 android:src 指定图像
RadioButton 与 Button 一样
动态改变 Button 的大小和布局
Button.layout 方法
按钮在不同状态下显示不同的图像
使用 drawable 资源的 <selector> 标签进行指定。<item android:state_pressed> 对应按下,具体可自行查询。
图像组件
图像半透明
- 重写 onDraw 之后通过 Paint.setAlpha 实现
- 通过 android:bachground 属性直接设置(#EFFF)
ImageView 显示图像的一部分
- 通过 Bitmap.createBitmap 截取某一部分之后创建这一部分的 Bitmap 对象
- 图像剪切资源 res/drawable 目录下创建资源,使用 <clip> 标签,最后还要使用 ClipDrawable.setLevel 方法设置
为图像加上边框
设置背景即可 QAQ
旋转和缩放图像
可以使用 Matrix.setRotate 方法旋转角度
进度组件
修改 ProgressBar 的颜色
在 res/drawable 下建立资源文件,通过 <layer-list> 标签修改
实现垂直进度条
drawable 下建立资源文件,通过 <clip> 设置之后,通过 ClipDrawable 对象进行截取使用
列表组件
BaseAdapter 的抽象方法:getItem, getItemId, getCount, getView
getItem:返回 Object 对象
getItemId:见方法名
getCount:返回列表数据的总数
getView:返回当前列表显示的 View 对象。其中的 convertView 参数如果为 null 表明没有对象可以利用,如果不为 null 可直接返回这个参数。
对列表组件(GridView, ListView)中的数据进行增 删 改操作
修改数据后,调用 Adapter.notifyDataSetInvalidated 通知列表组件更新数据
在调用此方法后系统会调用 getView 方法获取当前显示的列表项的 View 对象。更新数据流程完毕
在 ListView 组件中显示数据库中的数据
if(数据简单)
SimpleCursorAdapter
else
写一个继承自 CursorAdapter 的类,在 newView 方法中创建新的列表项 View 对象,在 bindView 方法中为相应的组件赋值
改变 ListView 的背景(颜色或者图像)
- android:listSelector
- ListView.listSelector
列表组件显示缩略图优化过程
优化原因:直接装载图像会卡顿
优化方式:异步处理,使用数组或 List 建立任务队列和数据缓冲。使用 BaseAdapter.notifyDataSetInvalidated 方法刷新列表中的数据。
为 ListView 组件加上快速滑块和修改快速滑块的方式
设置显示
- android:fastScrollEnable="true"
- ListView.setFastScrollEnable(true)
设置修改
不能直接修改,但可以通过反射技术修改图像
容器组件
SDK 支持的容器组件
容器组件即可以容纳子组件的组件,只要是 ViewGroup 的子类,就是容器组件。
五大布局组件(Framelayout, LinearLayout, RelativeLayout, TableLayout, AbsoluteLayout)、GridView、Gallery、ListView
容器内的组件可以水平和垂直滑动
ScrollView 和 HorizontalScrollView 组件结合使用。具体方式是互相嵌套
Gallery 循环显示图像
使 Adapter.getCount 返回一个较大的值(如 Integer.MAX_VALUE),
当 getView 不能直接通过 position 参数获得数据位置时,position = position % loopValue;
自定义组件
动态引用组件及类型
静态引用
组件连同主程序一起封装在编译后的目标文件中
静态引用组件类型
包含 .class 文件的 jar 文件; NDK Library(.so 文件);另一个 Java 工程
动态引用
主程序与组件是分离的。组件可以单独升级和卸载(不需要对主程序进行操作)
动态引用的组件类型
未安装的APK文件;包含 classes.dex 文件的 jar 文件、JavaScript 脚本、四大应用程序组件
自定义可视组件
三种方式
- 扩展/修改现有的组件。直接继承然后重写即可
- 组合多种组件。直接继承容器组件,将多个组件添加到组件类中
- 直接从 View 继承。此类组件需要从零开始编写
注意事项
可以将组件相关的 .class 文件单独放在 jar 文件中,并且将组件需要的资源以属性形式提供给调用者设置。
如果要考虑分辨率,需要使用 Java 代码将 dp 转换成 px
四大组件封装 jar 文件中的注意事项
使用的时候静态引用,注意要在 AndroidManifest.xml 文件中进行注册,否则无法使用
动态加载未安装 apk 文件中的类
加载流程
虚拟机装载 -> 创建对象实例 -> 利用 Java 反射技术获取 Method 对象 -> 调用类中的方法并获取方法返回值
apk 文件调用注意
如果 apk 文件中的类实现了接口,或继承了其他的类,必须要同时装载这些接口和类,否则无法成功创建该类的对象
应用程序动态引用 jar 包
JVM 格式的 jar 不能被 Android 应用程序动态调用,但包含 classes.dex 文件的可以。命令:jar cvf my.jar classes.dex
判断某个 Activity action 的 Android 应用程序是否安装
调用 PackageManager.queryIntentActivites 方法可以查询(具体实现可以去看 API)
在 Android 中与 JavaScript 进行交互
WebView 组件
NDK 方法的命名规则
Ps:具体请自己搜索
NDK 访问 Java
同上
动态组件 Android Market 内置下载
同上
四大应用程序组件
Android 中的窗口:Activity
设置一个 Activity 为启动窗口
在 AndroidManifest.xml 中定义 action 和 category
生命周期以及显示和销毁过程中方法执行的顺序
onCreate(Bundle savedInstanceState)
onStart()
onResume()
onPause()
onStop()
onRestart()
onDestory()
显示过程中:onCreate() -> onStart() -> onResume()
销毁过程中:onPause() -> onStop() -> onDestory()
在 onStop() 中重新获得了焦点,系统会调用 onRestart() -> onStart() -> onResume()
调用 Activity 的两种方法以及区别
显式调用
直接指定 Activity 进行调用
隐式调用
指定某一类 Activity 进行调用(如打开浏览器,拍照,电话之类)
Activity 传递数据
- Intent.putExtra() -> getIntent.getExtras();
- 定义为静态变量直接获取即可
- 保存到 Clipboard 剪切板。需要 ClipboardManager 进行管理。Tips:只能传递文本数据以及 Intent 对象支持的数据
- 在程序内创建一个全局对象,即 Application ,即可在应用程序的任何地方获取此对象。Tips:需要在 manifest 中注册
调用指定 Activity 的代码
Intent 传值。要想研究可以看看源码和 API
将 Activity 变成半透明的对话框
重写 Theme 对应的 style 中的 item name="android:windowBackground", 然后在 manifest 中 Activity 下指定 theme
设置 Activity 显示和关闭时的动画效果
startActivity 下面使用 overridePendingTransition(); 方法设置特效。具体查 API
广播接收器:Broadcast Receiver
接收广播
写一个继承自 BroadcastReceiver 的类。onReceive 方法中编写代码处理广播。Tips:广播接收器必须注册在 manifest 里面
如需处理多个广播,使用 intent.getAction 方法判断接收到的是哪一个。
获取短信内容
Ps:具体请自己搜索。
拦截来电
在 onReceive 方法中使用 TelephonyManager.getCallState 的返回值进行处理。Tips:需要在 manifest 中注册和声明权限<action>
拦截手机屏幕休眠和唤醒
通过两个 Broadcast Action 可以拦截
休眠状态:Intent.ACTION_SCREEN_ON
唤醒状态:Intent.ACTION_SCREEN_OFF
设置开机启动
使用广播接收器拦截手机启动广播,然后在 onReceive 中设置动作。Ps:具体搜索开机启动。
发送广播
通过 sendBroadcast 方法发送广播。具体流程:指定广播动作 -> 添加 category -> 发送广播
服务:Service
Service 生命周期
onCreate()
onStart(Intent intent, int startId)
onDestory()
调用顺序依次向下。调用方使用 startService 开始服务, stopService 结束服务。
onStart() 和 onDestory() 方法平级。除了创建。只有彻底销毁后才会调用 onStart()
开发 AIDL 服务的步骤
概述
AIDL (Android Interface Definition Language)是 Service 的一种重要应用,允许一个应用程序访问另一个应用程序中的对象。
步骤
- 右键建立一个扩展名为 aidl 的文件
- 如果内容正确,ADT 会自动生成一个 Java 接口文件
- 建立一个服务类(Service的子类)
- 实现由 aidl 文件生成的 Java 接口
- 在 AndroidManifest 中配置 AIDL 服务。Tips:<action> 标签中的 android:name 的属性就是客户端要引用该服务的ID, 也就是 Intent 类构造方法的参数值
AIDL 服务支持哪些类型的数据
- Java 简单类型 (int char boolean 等)。不需要导入(import)。
- String 和 CharSequence。不需要导入(import)。
- List 和 Map。注意:对象的元素类型必须是 AIDL 支持的数据类型。不需要导入(import)。
- AIDL 自动生成的接口。需要导入(import)。
- 实现 android.os.Parcelable 接口的类。需要导入(import)。
AIDL 服务在使用过程中有哪些需要注意
- 需要通过此服务传递的对象除了必须实现 android.os.Parcelable 接口外,
还必须包含一个名为 CREATOR 的变量,用于创建 Product 对象(Parcelable.Creator,具体自查)。
- 一个完整的 AIDL 服务除了实现代码,还需要建立 aidl 文件,并且在 AndroidManifest.xml 文件中进行配置。
- 客户端要调用 AIDL 服务首先需要绑定服务,然后会获取 AIDL 服务对象。接下来就可以像普通 Java 对象一样访问 AIDL 服务了。
内容提供者:Content Provider
读取联系人信息
- 通过 getContentResolver().query 进行查询
- 使用 Cursor 容器来装载查询返回结果
- 记得要在 AndroidManifest 之中添加权限
查询收发短信
- 通过 getContentResolver().query() 进行查询
- 使用 Cursor 容器来装载查询返回结果
- 记得要在 AndroidManifest 之中添加权限
Content Provider URI 由哪几部分组成
四个部分
content://: 相当于 HTTP URI 中的 http://。
authority: 相当于 HTTP URI 中的域名。
路径(path)。
参数(param)。
例子:content://mobile.android.mydata/product/20
其中 authority 是 mobile.android.mydata, path 是 product, param 是 20
Content Provider 的开发步骤
- 1 编写一个继承自 ContentProvider 的类。
- 2 实现 ContentProvider 类中的所有抽象方法。
- 3 定义 ContentProvider 的 URI 。其形式为: content://authority/path/param 。一般情况下 authority 建议使用域名
- 4 在 static 块中使用 UriMatcher 对象映射 Uri 和返回码
- 5 根据实际的需要实现相应的方法。比如如果只读就只实现 query, 其他 insert, delete, update 方法直接抛出异常即可。
- 6 实现 query、insert、delete、update 方法时要使用 UriMatcher.match 方法将 URI 映射成第4步与 URI 对应的代码。
- 7 在 AndroidManifest.xml 文件中使用 <provider> 标签注册 Content Provider, 其中 android:authorities 值就是第 4 步的 authority
Content Provider 添加权限
在 AndroidManifest.xml 文件中定义 ContentProvider 时可以指定权限。
除了在 <provider> 标签中指定访问权限外,还需要 <permission> 或 <user-permission> 标签