├── 独孤九剑.jpg
├── Android-独孤九剑.png
├── README.md
├── 第十天_多媒体编程.md
├── 第四天_网络编程.md
├── 第十一天_新特性、样式与主题.md
├── 第五天_网络编程.md
├── 第二天_数据存储和读取.md
├── 第八天_服务.md
├── 第一天_Android入门.md
├── 第九天_内容提供者.md
├── 第六天_Activity页面跳转和数据传递_.md
├── 第三天_数据存储和界面展现.md
├── 第七天_广播与服务.md
└── LICENSE
/独孤九剑.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuGuQiuBai/Android-Notes/HEAD/独孤九剑.jpg
--------------------------------------------------------------------------------
/Android-独孤九剑.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuGuQiuBai/Android-Notes/HEAD/Android-独孤九剑.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## Android基础笔记
3 | - 适合零基础入门。
4 | - 此笔记是本人辛辛苦苦一个个字码出来的,转载请保留出处。
5 |
6 | ## Disclaimer
7 | 版权归原作者所有,欢迎自由转载-非商用-非衍生-保持署名和链接。
8 |
--------------------------------------------------------------------------------
/第十天_多媒体编程.md:
--------------------------------------------------------------------------------
1 |
2 | ##多媒体编程
3 |
4 |
5 | 文本、图片、音频、视频
6 |
7 | #图片的处理
8 | -----
9 | ###01 计算机表示图形的形式
10 |
11 | 图片的大小 = 图片的总像素 * 每个像素的大小
12 |
13 | Android用ARGB表示颜色信息:每个像素占4个字节
14 |
15 | 1. bmp高质量保存
16 | 单色:只能表示两种颜色,黑和白
17 | 需要使用两个数字:0和1
18 | 需要使用一个长度为1的二进制数字
19 | 每个像素占用1/8个字节
20 | 16色:只能表示16种颜色
21 | 需要16个数字:0-15
22 | 换算成二进制表示:0000 - 1111
23 | 需要一个长度为4的二进制数字
24 | 每个像素占用1/2个字节
25 | 256色:只能表示256种颜色
26 | 需要256个数字:0-255
27 | 二进制表示:0000 0000 - 1111 1111
28 | 需要长度为8的二进制数字
29 | 每个像素占用1个字节
30 | 24位色:
31 | 每个像素需要24位
32 | 每个像素占用3个字节
33 | R:0-255
34 | G:同上
35 | B:同上
36 |
37 | 2. png 较高的质量保存图片
38 | - 图片压缩算法。把相似的颜色压缩在一起。
39 | 3. jpg 良好的质量保存
40 | - 图形压缩算法。把相似的颜色给合并在一起,用同一种颜色代替。
41 |
42 | ###02 加载大图片的OOM异常
43 | Out of memory on a 30720012-byte allocation. 29M
44 |
45 | ###03 缩放图片并加载到内存中
46 |
47 | 1. 拿到图片宽高
48 | 2. 拿到手机屏幕的宽高
49 | 3. 得到合适的比例值
50 | 4. 缩放图片显示在手机上
51 |
52 | ###04 在内存中创建原图的副本(重点)
53 | - 原因:要给图片加特效,Android不允许直接操作原图,只能操作原图的副本
54 | - 创建步骤:
55 |
56 | 1. 拿到原图
57 | 2. 创建和原图一样样的空白纸张
58 | 3. 把空白的纸张铺在画板上
59 | 4. 创建画笔
60 | 5. 开始画画
61 |
62 | ###05 图形处理的API(重点)
63 |
64 | 1.缩放
65 | 2.平移
66 | 3.旋转
67 | 4.镜面
68 | 5.倒影
69 |
70 | ###06 画画板
71 | 获取手指触摸手机屏幕的XY坐标,然后用线连接起来
72 |
73 | ###07 撕衣服
74 |
75 | 原理:在界面上放两张图片,没有穿衣服的图片显示在下面,穿衣服的图片是显示在上面.
76 | 手指在屏幕滑动的过程中,把手所到之处的像素点改变成透明色.
77 |
78 |
79 |
80 | #音频
81 | -----
82 | ###08 音乐播放器API
83 | MediaPlayer
84 |
85 | ###09影音播放器的生命周期函数
86 |
87 | 状态:
88 |
89 | 1.空闲:reset() 重新设置,new MediaPlayer()
90 | 2.初始化:setDataSource()设置播放的数据资源
91 | 3.准备:prepare(),prepareAsync()准备方法
92 | 4.播放:start()播放
93 | 5.播放完成:一直播放
94 | 6.停止:stop()停止
95 | 7.暂停:pause()暂停
96 | 8.结束:release()释放
97 | 9.错误:程序抛出异常
98 |
99 |
100 |
101 | #视频
102 | -----
103 | ###10 视频播放器videoview
104 |
105 |
106 |
107 | #照相机
108 | -----
109 | ###11 照相机拍照(重点)
110 | 采用隐式意图打开系统相机应用程序的拍照界面
111 |
112 | ###12 录像机应用
113 | 采用隐式意图打开系统相机应用程序的录像界面
114 |
--------------------------------------------------------------------------------
/第四天_网络编程.md:
--------------------------------------------------------------------------------
1 |
2 | #通过网络从服务器获取数据
3 |
4 | #网络通信
5 | -----
6 | ###01 网络图片查看器(重点)
7 | 1. 创建Url对象
8 | 2. 用Url对象打开连接
9 | 3. 设置请求参数,设置请求方式
10 | 4. 拿到返回状态 返回码:200成功 3xx重定向 4xx资源错误 5xx服务器错误
11 | 5. 从连接中获取服务端返回的二进制输入流
12 | 6. 在清单文件中添加访问互联网的权限
13 |
14 |
15 | ###02 为什么子线程不能修改UI界面?
16 |
17 | - NetworkOnMainThreadException:网络在主线程上的异常;
18 |
19 | 从Android4.0开始,google为让UI界面运行的更加流程,要求在主线程中不能有访问网络的操作,这样就防止UI界面卡死的现象。
20 | 所以通过子线程来访问网络,但子线程不能直接修改UI界面,要通过handler传送消息,请求主线程修改。
21 |
22 | - android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
23 |
24 | 从错误线程调用的异常
25 | 只有主线程才能修改UI
26 |
27 | - ANR applicationg not response 应用程序无响应
28 |
29 | ###03 消息处理机制的原理(重点)
30 | - 原理:如图
31 |
32 | - 使用handler的步骤:
33 |
34 | 1. 在主线程中初始化Handler
35 | 2. 在子线程中用handler发送消息
36 | 3. android系统处理消息
37 | 4. 在Handler的handlemessage()方法中处理消息
38 |
39 | - Handler的工作原理(handler,message,looper三者之间的关系):
40 |
41 | 在子线程中给主线程发送消息,在Handler的handlmessage()方法中处理消息
42 |
43 | ###04 网络源码查看器
44 | - 网络请求
45 | - Handler消息机制
46 |
47 | ###05 消息处理常用的另一个API
48 | 这个方法是运行在ui线程
49 | runOnUiThread(new Runnable() {
50 | @Override
51 | public void run() {
52 | // 修改UI界面
53 | textView.setText("更改UI");
54 | }
55 | });
56 |
57 |
58 |
59 | #阶段总结
60 | -----
61 | ###06 新闻客户端
62 | 1. 从服务器获取xml数据
63 |
64 | 1. 创建Url对象,用Url对象打开连接
65 | 2. 设置请求参数
66 | 3. 拿到返回状态 返回码:200成功 3xx重定向 4xx资源错误 5xx服务器错误
67 | 4. 从连接中获取流
68 | 2. 解析XML文件
69 |
70 | 1. 初始化xml解析器
71 | 2. 设置参数和输入流
72 | 3. 解析xml文件数据
73 | 数据写完了,单元测试一下xml文件的解析
74 | 3. 把List集合中的数据显示在ListView上
75 |
76 | ListView的编写步骤
77 | 设置数据适配器adapter
78 | 1. 在主线程中初始化Handler
79 | 2. 在子线程中用handler发送消息
80 | 3. android系统处理消息
81 | 4. 在Handler的handlmessage()方法中处理消息
82 |
83 | 4. 显示图片
84 |
85 | 自定义imageView的步骤
86 | 1. 写个SmartImageView继承ImageView,开发网络加载图片的方法
87 | 2. 在xml布局中 包名+SmartImageView
88 | 3. 在getView方法中调用SmartImageView.setImageUrl()方法
89 |
90 |
91 |
92 | #使用开源框架
93 | -----
94 | ###07 使用SmartImageView显示新闻图片(重点)
95 | 1. www.github.com 下载开源框架
96 | 2. 阅读开源框架的介绍 readme.md 或者sample示例代码
97 | 3. 复制代码到我们的工程中
98 | 4. 在item.xml中使用smartimageview替换imageview,在代码中使用smartimageview替换 imageview,调用setImageUrl();
99 |
100 |
--------------------------------------------------------------------------------
/第十一天_新特性、样式与主题.md:
--------------------------------------------------------------------------------
1 | ##新特性、样式与主题
2 |
3 |
4 | #Fragment新特性(重点)
5 | ---
6 | ###01 Fragment入门
7 | Android3.0以后添加的功能,在同一Activity切换多个的布局文件。
8 |
9 | 编写步骤:
10 |
11 | // 1. 初始化Fragment实例对象
12 | Fragment01 f1 = new Fragment01();
13 | // 2. 拿到Fragment管理器
14 | FragmentManager fm = getFragmentManager();
15 | // 3. 获取Fragment的事务
16 | FragmentTransaction ft = fm.beginTransaction();
17 | // 4. 设置Fragment
18 | ft.replace(R.id.fl_content, f1);
19 | // 5. 提交
20 | ft.commit();
21 |
22 | ###02 Fragment向下兼容
23 | 全部用android-support-v4.jar里的类
24 |
25 | ###03 Fragment和Activity之间传递数据
26 | 1.在activity中给fragment:
27 | 把fragment作为一个普通的对象,调用它的方法接收参数;
28 |
29 | 2.在fragment中给activity传数据:
30 | 把activity作为一个普通的对象,调用它的方法接收参数;
31 |
32 | ###04 Fragment的生命周期
33 | 比Activity多:onAttach()onCrateView()onActivityCrated()
34 | onDestroyView()onDetach()
35 |
36 |
37 | 开发中常用:onCrateView()onDestroy()
38 |
39 | #属性动画
40 | ---
41 | ###05 为什么使用属性动画
42 | - 动画:从开始状态到结束状态的过渡效果
43 | - 补间动画:只有一个动画效果,并没有改变控件的x,y 坐标
44 | - 属性动画:既有动画效果,又可以改变控件的x,y坐标
45 |
46 | ###06 四种种常见属性动画
47 | 1. 平移:
48 |
49 | ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "translationX", 0, 100);
50 | oa.setDuration(2000);
51 | oa.setRepeatCount(2);
52 | oa.setRepeatMode(ObjectAnimator.REVERSE);
53 | oa.start();
54 | 2. 透明:
55 |
56 | ObjectAnimator oa2 = ObjectAnimator.ofFloat(iv, "alpha", 1, 0.5f, 0);
57 | oa2.setDuration(2000);
58 | oa2.setRepeatCount(1);
59 | oa2.setRepeatMode(ObjectAnimator.REVERSE);
60 | oa2.start();
61 |
62 | 3. 缩放
63 |
64 | ObjectAnimator oa3 = ObjectAnimator.ofFloat(iv, "scaleX", 1, 0.5f, 0.2f);
65 | oa3.setDuration(2000);
66 | oa3.setRepeatMode(ObjectAnimator.REVERSE);
67 | oa3.start();
68 | 4. 旋转
69 |
70 | ObjectAnimator oa4 = ObjectAnimator.ofFloat(iv, "rotationY", 0,20,45,360);
71 | oa4.setDuration(2000);
72 | oa4.setRepeatMode(ObjectAnimator.REVERSE);
73 | oa4.start();
74 |
75 | 一起飞:
76 |
77 | //创建一个动画师集合
78 | AnimatorSet as = new AnimatorSet();
79 | //一个一个装逼一个一个飞
80 | //as.playSequentially(oa1, oa2, oa3, oa5);
81 | //一起装逼一起飞
82 | as.playTogether(oa1, oa2, oa3, oa5);
83 | //设置播放动画的对象
84 | as.setTarget(iv);
85 | as.start();
86 |
87 |
88 | #样式与主题
89 | ---
90 | ###07 样式(重点)
91 | 主要作用于控件上,修饰控件的一些属性
92 |
93 | ###08 主题
94 |
95 | 界面或者整个应用程序的风格
96 |
97 | 定义主题的方法与定义样式完全一样
98 |
99 |
100 |
101 | #Android基础知识点复习
102 |
103 |
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/第五天_网络编程.md:
--------------------------------------------------------------------------------
1 | ##通过网络提交数据到服务器
2 | 使用get和post向服务器提交数据、多线程断点下载
3 |
4 |
5 | #使用get和post向服务器提交数据
6 | -----
7 |
8 | ##http的get和post协议
9 | ###01 使用GET方式向服务器端提交数据
10 |
11 | 组拼url的路径,把提交的数据拼装url的后面,提交给服务器。
12 |
13 | 缺点: 1. 安全性 2. 长度有限制不能超过4K
14 | 优点: 代码写起来很简单
15 |
16 | ###02 使用POST方式向服务器端提交数据
17 |
18 | 数据是以流的方式写给服务器
19 |
20 | 优点:1.安全 2. 长度没有限制
21 | 缺点:代码编写麻烦
22 |
23 | 和GET方式的不同:
24 | 1. 调用的url地址不一样:使用post方式没有把参数组拼到url地址的后面;
25 | String path = "http://192.168.1.100:8080/web/servlet/
26 | 2. 请求方式不同:POST;
27 | conn.setRequestMethod("POST");
28 | 3. 设置的请求参数不同,多了两个参数:Content-Type: application/x-www-form- urlencoded,Content-Length: 25;
29 | conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
30 | conn.setRequestProperty("Content-Length", data.length()+"");
31 | 4. 使用二进制输出流把提交的参数写到服务器端;
32 | 设置是否允许向服务器端写数据
33 | conn.setDoOutput(true);
34 | 使用二进制输出流把数据写到服务器端;
35 | conn.getOutputStream().write(data.getBytes());
36 |
37 | ###03 post&get方式提交数据的中文乱码解决
38 |
39 | - 产生乱码的原因:客户端和服务端两边的码表不一样
40 |
41 | - 解决方案:客户端和服务端两边采用相同的码表,项目中都是用UTF-8的编码
42 |
43 | - 常见中文乱码:菱形有问号 gbk的中文数据用utf-8显示。
44 |
45 | - 常见乱码问题:
46 |
47 | Android客户端默认使用的字符集编码为UTF-8
48 | 1. 服务器端返回的中文数据是乱码:
49 | 保持服务器端和客户端使用的字符集编码一致;
50 | 2. 客户端提交给服务器端的中文数据时乱码:
51 | 保持服务器端和客户端使用的字符集编码一致;
52 | URLEncoder.encode(qq,"UTF-8")
53 |
54 |
55 | ##开源框架HttpClient
56 | ###04 使用HttpClient向服务器端提交数据(重点)
57 |
58 | - HttpClient 开源的,轻量级的浏览器,代码模拟浏览器的行为;
59 | google已经把httpclient的api已经集成到了Android里了.不需要自己单独下载了;
60 |
61 | - 使用步骤:
62 |
63 | 1.创建一个浏览器对象;
64 | 2.输入网址;
65 | 3.敲回车;
66 |
67 |
68 | ##开源框架Asynchttpclient
69 | ###05 使用开源项目Asynchttpclient的GET和POST访问网络(重点)
70 |
71 | - Asynchttpclient内部使用线程池访问网络,
72 | 不需要考虑主线程子线程的问题
73 | - 自动进行了UTF-8的编码了
74 | - 使用handler处理消息了
75 |
76 | ###06 上传文件
77 |
78 | 可以向服务器提交任意类型的文件数据
79 |
80 |
81 |
82 | #多线程断点下载
83 | -----
84 | ###07 多线程加速下载的原理
85 | 1. 为什么需要多线程下载?
86 | 为了提高从服务器下载资源速度
87 |
88 | 2. 下载速度的限制条件?
89 | 网络带宽
90 |
91 | ###08 多线程下载的原理
92 | 如图
93 |
94 | ###09 断点下载的原理
95 |
96 | 在下载的过程中实时记录下载到的位置,下次下载时接着上一次的位置下载;
97 |
98 | ###10 多线程下载的Android移植
99 | 1. android程序和java程序运行环境的区别
100 | - 写UI,动态添加progressBar
101 | - 添加网络权限和SD的读写权限
102 |
103 | 2. 复制代码修改错误
104 | - 去掉static修饰符
105 | - 修改存储文件的路径为SD卡
106 |
107 | 3. 设置progressBar的进度
108 |
109 | 4. 测试
110 |
111 | ###11 使用开源实现多线程下载(重点)
112 | - Xutils
113 | - Afinal
114 |
115 |
116 |
117 |
118 |
119 |
--------------------------------------------------------------------------------
/第二天_数据存储和读取.md:
--------------------------------------------------------------------------------
1 | ##Android中的数据存储和读取
2 | 存储数据到文件中、从文件中读取数据显示在界面上
3 |
4 | #测试
5 | -----
6 | ###1 软件测试的概念
7 | 1. 按照是否知道源代码
8 | - 白盒测试:知道源代码,写代码去测试逻辑
9 | - 黑盒测试:不知源代码,根据需求测试软件的功能
10 |
11 | 2. 按照测试的粒度
12 | - 方法测试:测试某个方法
13 | - 单元测试:测试一个代码块
14 | - 功能测试:根据需求测试软件的某个功能
15 |
16 | 3. 按照测试的暴力程度
17 | - 压力测试
18 | - 冒烟测试:monkey
19 |
20 | ###2 Android下编写单元测试代码的步骤
21 | 1. 测试类 extends AndroidTestCase
22 |
23 | 2. 测试方法
24 | * 必须是public
25 | * 给android测试框架抛出异常
26 |
27 | 3. 要对测试方法断言
28 |
29 | 4. 在manifest节点写:
30 |
31 |
34 |
35 | 在application节点写:
36 |
37 |
38 |
39 | 5. 右键部署程序运行单元测试
40 | - 绿条代表通过
41 | - 红条代表失败,方法有问题
42 |
43 |
44 | Android中查看日志
45 | -----
46 | ###3 日志等级的划分
47 | 分为5个等级:
48 |
49 | V: verbose 提醒 黑色 Log.v();
50 | D: debug 调试 蓝色 Log.d();
51 | I: info 信息 绿色 Log.i();
52 | W: warn 警告 橘黄 Log.w();
53 | E: error 错误 红色 Log.e();
54 |
55 | ###4 什么是上下文 Context
56 | 全局的环境对象,方便的api,可以去获取整个应用程序的数据
57 |
58 |
59 | #Android中文件存储数据
60 | -----
61 | RAM:运行内存,相当于电脑的内存
62 |
63 | ROM:内部存储,相当于电脑的硬盘,可以持久化存储数据
64 |
65 | SD卡:外部存储
66 |
67 | ##5 内部存储(重要)
68 | 文件存储路径: /data/data/包名
69 |
70 | 文件只能存储在自己应用程序私有的文件夹下,别的应用程序无法访问
71 |
72 | 1. this.getFilesDir() == /data/data/包名/files/
73 |
74 | 清除数据,弹出对话框提示,会清除所有的数据
75 |
76 | 2. this.getCacheDir() == /data/data/包名/cache/
77 |
78 | 清除缓存,没有对话框提示,只清除cache目录里面的数据,当系统内存严重不足时,系统会自动清除cache目录里面的文件
79 | 应用场景:存储临时的文件
80 |
81 | 3. 输入流 this.openFileInput("config.txt");
82 |
83 | 4. 输出流 this.openFileOutput("config.txt", 0);
84 |
85 | ##6 外部存储SD卡(重要)
86 | 记得添加权限,检查外部存储设备的状态和可用空间
87 |
88 | ###7 SD卡的路径、状态、可用空间大小
89 | - SD卡的路径:
90 | Environment.getExternalStorageDirectory()
91 |
92 | - SD卡的状态:
93 | Environment.getExternalStorageState()
94 |
95 | - SD卡的可用空间
96 |
97 | File file = Environment.getExternalStorageDirectory();
98 | long size = file.getFreeSpace();//byte
99 | String num = Formatter.formatFileSize(this, size);
100 |
101 | ##8 SharedPreference存储数据(重要)
102 | 文件存储路径: /data/data/包名/shared_prefs/
103 |
104 | 1. 初始化 SharedPreferences
105 | mPreferences = this.getSharedPreferences("info", 0);
106 |
107 | 2. 拿到 Editor编辑器
108 | Editor editor = mPreferences.edit();
109 |
110 | 3. 存储数据
111 | editor.putString("qq", qq);
112 |
113 | 4. 提交,重要
114 | editor.commit();
115 |
116 | 应用场景:存储配置信息,账号密码
117 |
118 | ##9 Android下文件访问的权限
119 | 原理:底层是通过Linux操作系统的文件模式来实现的。
120 |
121 | 默认情况下,所有的文件创建出来都是私有的。只有自己的应用程序可以访问里面的数据,别的应用程序是不可以访问数据的。
122 |
123 |
124 |
125 | #Xml文件生成和解析
126 | -----
127 | ###10 为什么要用xml文件
128 | - 用元素描述数据
129 | - 跨平台
130 |
131 | ###11 生成xml文件的步骤(重要)
132 | 1. 初始化xml序列器
133 |
134 | XmlSerializer serializer = Xml.newSerializer();
135 |
136 | 2. 设置参数
137 |
138 | FileOutputStream os = this.openFileOutput("student.xml", 0)
139 | serializer.setOutput(os, "utf-8");
140 |
141 | 3. 往xml文件里面写数据
142 |
143 | serializer.startDocument("utf-8", true);
144 |
145 | ###12 解析xml文件的方式
146 | 1. sax 基于事件
147 | 2. dom&dom4j 把xml加载到内存
148 | 3. pull解析(类似于sax但是效率更高,内存开销更小)
149 |
150 |
151 | ###13 解析xml文件(重要)
152 | 1. 初始化xml解析器
153 | XmlPullParser parser = Xml.newPullParser();
154 | 2. 设置解析器的参数 输入流
155 | parser.setInput(is, "utf-8");
156 | 3. 解析数据
157 |
158 |
--------------------------------------------------------------------------------
/第八天_服务.md:
--------------------------------------------------------------------------------
1 | #服务
2 |
3 | ##01 start开启服务的生命周期(重点)
4 |
5 | - 生命周期方法:oncreate() -->onstartCommand()--->onstartCommand()--->onDestory()
6 |
7 | 1.onCreate:在服务对象创建后调用这个方法,初始化服务对象
8 | 2.onStartCommand:开启服务后调用这个方法
9 | 3.onDestroy:在服务对象被销毁之前调用这个方法,通常在这个方法中做一些扫尾工作,比如保存数据
10 |
11 | - 特点:
12 |
13 | 1.第一次开启服务时,先创建服务对象,然后再开启
14 | 调用的方法:onCreate,onStartCommand
15 | 2.停止服务调用方法:onDestroy()
16 | 3.服务可以被多次开启,每次开启时只调用onStartCommand方法
17 | 4.服务只能被停止一次,如果多次停止不会调用任何方法
18 | 5.没有界面,可以长期运行在后台(即使界面关闭掉了)
19 |
20 | ##02 bind开启服务的生命周期(重点)
21 | - 生命周期方法: onCreate()-->onBind()-->onUnbind()-->onDestroy()
22 |
23 | 1.onCreate:在服务对象创建后调用这个方法,初始化服务对象
24 | 2.onBind()绑定服务
25 | 3.onUnbind()解除绑定的服务
26 | 4.onDestroy:在服务对象被销毁之前调用这个方法,通常在这个方法中做一些扫尾工作,比如保存数据
27 | - 特点:
28 |
29 | 1.第一次绑定服务时,先创建服务对象,再绑定
30 | 调用的方法onCreate,onBind
31 | 2.解除绑定服务后服务就会停止
32 | 3.服务只能被绑定一次
33 | 4.服务只能被解除一次,多次解除会抛出异常
34 |
35 | - 小细节:
36 |
37 | 1.如果onbind方法返回值是null,onServiceConnected方法就不会被调用
38 | 2.绑定的服务在系统设置界面,正在运行条目是看不到的
39 | 3.用的是什么conn绑定的,就必须用哪个conn去解绑
40 | 4.绑定的服务,不求同时生,但求同时死。 如果调用者Activity退出了,服务就自动跟着退出
41 |
42 |
43 | ##03 绑定服务调用服务里的方法
44 |
45 | 服务被绑定成功时,返回服务代理人;服务被连接成功时,拿到服务代理人
46 |
47 | 1. 在Activity里绑定服务bindService()
48 |
49 | bindService(intent, new MyConn(), BIND_AUTO_CREATE)
50 | intent: 意图对象,服务对应的意图对象 new Intnet(this,Service.class)
51 | ServiceConnection: 通讯频道,利用他可以获取到服务成功绑定后得到的代理人
52 | BIND_AUTO_CREATE:常量,服务不存在会自动创建
53 |
54 | 2. 如果服务被成功绑定,会执行 onBind的方法,让返回服务的代理人对象(IBinder类型)
55 | 返回值 IBinder 就是服务内部的小蜜
56 |
57 | 3. 扩展实现服务内部的代理人,可以间接的调用服务的方法
58 |
59 | public void callMethodInService(int money){
60 | if(money>500){
61 | methodInService();
62 | }else{
63 | Toast.makeText(DemoService.this, "这点钱还想办事呀?", 0).show();
64 | }
65 | }
66 | 4. 采用内部类的方式得到服务连接的通道
67 |
68 | private class MyConn implements ServiceConnection{
69 | //当服务被成功连接的时候调用的方法
70 | @Override
71 | public void onServiceConnected(ComponentName name, IBinder service) {
72 | 重要的参数IBinder ,代表的就是中间人,服务的小蜜
73 | }
74 | //当服务失去连接的时候调用的方法
75 | @Override
76 | public void onServiceDisconnected(ComponentName name) {
77 | }
78 | }
79 | 5. 在MyConn成功连接后,就得到了 IBInder对象即MyBinder
80 |
81 | 6. 利用MyBinder代理人间接调用服务的方法
82 |
83 | ##04 绑定服务抽取接口(重点)
84 |
85 | 接口: 可以隐藏代码内部的细节,只暴露程序员想暴露的方法
86 |
87 | 1. 在工程中添加一个接口IService,在里面写一个方法callMethodInService()
88 |
89 | 2. 让服务的代理人实现IService接口,实现接口的方法,在这个方法中调用服务的业务方法
90 |
91 | 3. 服务被绑成功时,返回服务的代理人对象(IBinder类型)
92 |
93 | 4. 服务连接成功时,拿到代理人IBinder,将其强转成IService类型
94 |
95 | 5. 在activity中,通过调用代理人IService接口暴露出来的方法,间接调用服务里的业务方法
96 |
97 | ##05 混合方式开启服务,服务的生命周期
98 |
99 | 1. 为什么需要采用混合的方式开启服务?
100 |
101 | - startService 服务长期后台运行,不可以调用服务里面的方法
102 |
103 | - bindService 可以调用服务的方法,但是不能长期后台运行
104 |
105 | - 采用混合的方式开启服务:
106 | 即想服务长期在后台运行,又可以调服务里的方法
107 |
108 | 2. 特点:
109 |
110 | 1. 如果服务被绑定了,只有解除绑定才能停止服务
111 | 2. 如果服务被采用start的方式开启过,只有stopService()才能停止服务
112 |
113 | 3. 推荐使用的步骤:
114 |
115 | 1. startService(): 为了保证让服务长期运行在后台;
116 | 2. bindService(): 绑定服务,调用服务中业务方法;
117 | 3. unBindService(): 解除绑定,不再调用服务中业务方法;
118 | 4. stopService(): 停止服务
119 |
120 | ##06 服务的应用场景
121 |
122 | 应用场景:需要写一些代码运行在后台,执行一些任务.
123 |
124 | ##07 IPC进程间通信
125 | - inter process communication 进程间通信
126 | - aidl : android interface defination language安卓接口定义语言
127 | 满足两个进程之间接口数据的交换(ipc)
128 |
129 |
130 | ##08 本地服务和远程服务
131 | * 本地服务: 服务的代码在自己应用程序工程的内部
132 |
133 | * 远程服务: 同一个设备上的另一个软件中的服务组件
134 |
135 | - 通过aidl接口暴露远程服务中的方法,任何应用程序都可以调用远程服务中的业务方法
136 |
137 | ##09 本地应用调用远程服务中方法 aidl的写法(重点)
138 |
139 | 通过aidl接口把远程服务中的业务方法暴露出去
140 |
141 | 1. 创建一个远程服务的工程,写一个服务的组件,在服务中写一个业务方法
142 |
143 | 1. 在远程服务中把IService.java改成IService.aidl
144 | 把文件中public修饰符删除了
145 | 在工程目录gen目录下会自动编译成IService.java的接口文件。
146 |
147 | 2. 在远程服务中让代理人继承IService.Stub,Stub是远程服务的代理对象
148 |
149 | 2. 创建本地应用,调用远程服务中方法:
150 |
151 | 3. 在本地应用中创建一个包,包名必须与远程服务中IService.aidl文件所在包名相同
152 | 4. 把远程服务中IService.aidl文件拷贝到本地应用的这个包下面
153 | 5. 在本地应用连接服务成功时,得到服务返回的代理人对象
154 | mBinder = IService.Stub.asInterface(service)
155 | 6. 通过远程服务代理人对象间接调用远程服务中的业务方法
156 |
157 | ##10 远程服务的使用场景
158 | 1. 超级大公司,写出来逻辑供别的程序员使用
159 | 2. 手机企业,手机定制厂商,提供一些方便的逻辑供程序员使用。snoy手机,人脸识别
160 | 3. 系统源码,内置很多的服务。电话服务TelephoneyManager LayoutInflaterService
161 |
--------------------------------------------------------------------------------
/第一天_Android入门.md:
--------------------------------------------------------------------------------
1 |
2 | ##Android入门
3 | 搭建Android开发环境、Android应用开发的步骤
4 |
5 | #什么是Android
6 | -----
7 | ###1 Android历史&版本
8 |
9 | Android2.3.3 安卓2.0后最稳定的版本 API:10
10 | Android3.0 增加了新特性,针对平板电脑的系统
11 | Android 4.1.2 安卓4.0后最稳定的版本 API:16
12 |
13 | ###2 Android系统四层架构
14 |
15 | 1. 应用程序层:安装在手上的软件都属于这一层
16 |
17 | 2. 程序框架层:开发程序调用的API都在这一层
18 |
19 | 3. 基础类库层:第三方开源的框架,dvm
20 |
21 | 4. linux kernel:各种驱动
22 |
23 |
24 | #搭建Android开发环境
25 | -----
26 | ###3 搭建Android开发环境
27 |
28 | 1. Eclipse+ADT
29 | - ADT Android Developer Tools 安卓开发工具,Eclipse的插件
30 | - v21.xxx 最新的23.xxx
31 |
32 | 2. Android Studio
33 | - 对硬件要求高
34 |
35 | ###4 SDK的目录结构
36 | Standard Developer Kits 标准的开发工具包
37 |
38 | * add-ons
39 | >附加组件,放在一个额外的工具。google api,提供google地图的jar包
40 | * build-tools
41 | >编译工具,谷歌sdk升级后采用的目录
42 | * docs
43 | >文档目录。开发文档。(了解)
44 | * extras
45 | >附加工具 support 文件夹,提供向下兼容的jar包。
46 | >和额外的驱动,摄像头驱动,手机驱动
47 | * platform
48 | >开发平台(了解)
49 | * platform tools
50 | >开发的工具
51 | * sample
52 | >实例代码(了解)
53 | * source
54 | >源代码 (了解)
55 | * system-image
56 | >系统镜像
57 | * tools
58 | >开发工具(了解)
59 |
60 | ###5 模拟器
61 | Android Virtual Device 模拟器
62 |
63 | 手机屏幕分辨率:
64 | VGA 640*480 (Video Graphics Array)
65 | QVGA 320*240 (Quarter VGA)
66 | HVGA 480*320 (Half-size VGA)
67 | SVGA 800*600 (Super VGA)
68 | WVGA 800*480 (Wide VGA)
69 | FWVGA 854*480 (Full Wide VGA)
70 |
71 | ###6 Android工程的目录结构
72 | * src
73 | > 源代码
74 | * gen
75 | > 工具自动生成的代码
76 | >BUildconfig 调试的开关 默认开启
77 | >R.java 很多的静态的内部类
78 | * android.jar
79 | >开发用的jar包
80 | * android dependence
81 | > 依赖,向下兼容的依赖jar包
82 | * assets
83 | >资产目录 存放一些别的类型的文件
84 | * bin
85 | >eclipse工具编译的文件夹
86 | * libs
87 | >应用程序开发用的jar包
88 | * res
89 | >应用程序的资源
90 | * androidmanifest.xml
91 | > 清单文件
92 |
93 | ###7 Eclipse打包安装应用的过程
94 | 1. 生成apk文件.
95 |
96 | 1.1 把classes中的字节码文件打包通过命令dx.bat打包成一个classes.dex.
97 | 1.2 resources.arsc文件的生成.
98 | 1.3 未编译的资源文件.
99 | 1.4 把清单文件AndroidManifest.xml文件转换成二进制文件.
100 | 1.5 把以上生成的文件打包成一个压缩包(.apk)
101 |
102 | 2. 把apk文件上传到手机上
103 |
104 | 3. 安装apk应用程序
105 | - 创建一个文件夹/data/data/包名, 用于存放当前应用程序数据.
106 |
107 | ###8 常见的adb指令
108 | Android Debug Bridge 安卓调试桥
109 | 连接模拟器和Eclipse的工具
110 |
111 | * adb devices
112 | > 查看设备
113 |
114 | * adb install
115 | > 安装一个apk -r 覆盖安装
116 |
117 | * adb uninstall <包名>
118 | > 卸载一个apk,包名是应用程序的唯一标示,一个手机里面不可能有两个应用程序包名相同。
119 |
120 | * adb shell
121 |
122 | #Android应用程序开发
123 | -----
124 | ###9 Android应用程序开发的步骤(重要)
125 | 1. 产品经理给需求
126 | 2. UI给切图,UI设计图
127 | 3. 开发,写代码
128 |
129 | 1.在xml里面写UI布局
130 | 2.在activity中写代码,打架子
131 | 3.写具体的业务
132 | 4. 测试
133 |
134 | ###10 点击事件的四种写法(重要)
135 | 1. 匿名内部类的方式
136 |
137 | btn.setOnClickListener(new OnClickListener() {
138 |
139 | @Override
140 | public void onClick(View v) {
141 | System.out.println("你点击了按钮!!!");
142 |
143 | }
144 | });
145 |
146 | 简单点击事件的实现 一般都用匿名内部类
147 |
148 | 2. 内部类的方式
149 |
150 | btn.setOnClickListener(new MyOnClickListener());
151 |
152 | private class MyOnClickListener implements OnClickListener{
153 | public void onClick(View v) {
154 | System.out.println("内部类的方式,点击按钮");
155 | }
156 | }
157 | 3. 当前的activity implements OnClickListener{}
158 |
159 | btn1.setOnClickListener(this);
160 | public void onClick(View v) {
161 | System.out.println("你点击按钮!!!");
162 | int id = v.getId();
163 | switch (id) {
164 | case R.id.button1: //按钮1
165 | System.out.println("你点击了按钮1");
166 | break;
167 | case R.id.button2: //按钮2
168 | System.out.println("你点击了按钮2");
169 | break;
170 | default:
171 | break;
172 | }
173 | }
174 | 应用场景:界面上按钮比较多的时候,代码的可读性高
175 |
176 | 4. onClick属性
177 |
178 | public void click(View view){
179 | System.out.println("4. 点击按钮");
180 | }
181 |
182 | 应用场景:上课采用这种方式,开发中不建议使用
183 |
184 | ###11 五中常见ui布局(重要)
185 | 1. 线性布局 LinearLayout
186 |
187 | 重要属性 android:orientation="horizontal" 水平排列
188 | android:orientation="vertical" 垂直排列
189 | android:layout_width="0dip"
190 | android:layout_weight="1" 权重
191 | 2. 相对布局 RelativeLayout
192 |
193 | 原理:向前看,相对于某个控件的位置
194 | 3. 绝对布局 AbsoluteLayout
195 |
196 | 过时了,不推荐使用
197 | 应用:机顶盒开发常见
198 | 4. 表格布局 TableLayout
199 |
200 | 应用:办公类的软件
201 | 5. 帧布局 FrameLayout
202 |
203 | 一个控件浮在另一个控件的上方
204 |
205 |
206 |
--------------------------------------------------------------------------------
/第九天_内容提供者.md:
--------------------------------------------------------------------------------
1 |
2 | #内容提供者
3 |
4 |
5 | ##01 为什么需要内容提供者?
6 |
7 | 把应用程序私有的数据暴露给别的应用程序,让别的应用程序可以对自己私有的数据库实现增删改查。
8 |
9 | ##02 内容提供者编写步骤:
10 |
11 | 1. 写一个类继承了ContentProvider
12 |
13 | 2. 在清单文件中配置内容提供者,添加了provider节点,设置了android:authorities="cn.itcast.bankdb"
14 | authorities是内容提供者的主机名,就相当于一个网站的域名或者ip,可以根据这uri找到内容提供者;
15 |
16 | 3. 在内容提供者中添加匹配器 UriMatcher
17 |
18 | 4. 根据需求实现内容提供者的增删改查的方法
19 |
20 | ##03 调用另一个工程中内容提供者的步骤:
21 |
22 | 1. 得到系统提供的内容提供者解析器:
23 | ContentResolver resolver = this.getContentResolver();
24 |
25 | 2. 指定内容提供者的uri:
26 |
27 | 3. 通过解析器调用内容提供者的方法;解析器中的增删改查的方法是与内容提供者中的增删改查方法--对应的:
28 |
29 | ##04 内容提供者增删改查的实现
30 |
31 | - 在内容提供者实例对象创建后调用这个方法初始化实例对象:得到数据库的实例对象
32 |
33 | // 创建或者打开一个数据库实例对象
34 | public boolean onCreate() {
35 | return false;
36 | }
37 |
38 | - 增
39 |
40 | // 调用数据库的插入记录的方法,插入一条记录
41 | public Cursor query(Uri uri, String[] columns, String selection,
42 | String[] selectionArgs, String sortOrder) {
43 | int code = mUriMatcher.match(uri);
44 | // 判断用户传递过来的uri是否匹配成功
45 | if (code == ACCOUNT) {
46 | SQLiteDatabase db = helper.getReadableDatabase();
47 | Cursor cursor = db.query("account", columns, selection,
48 | selectionArgs, null, null, null);
49 | return cursor;
50 | } else {
51 | throw new IllegalArgumentException("根据法律规定,你无权查看数据。");
52 | }
53 | }
54 |
55 | - 删
56 |
57 | public int delete(Uri uri, String selection, String[] selectionArgs) {
58 | int code = mUriMatcher.match(uri);
59 | if (code == ACCOUNT) {
60 | SQLiteDatabase db = helper.getWritableDatabase();
61 | int result = db.delete("account", selection, selectionArgs);
62 | db.close();
63 | return result;
64 | } else {
65 | throw new IllegalArgumentException("根据法律规定,你无权删除数据。");
66 | }
67 | }
68 | - 改
69 |
70 | public int update(Uri uri, ContentValues values, String selection,
71 | String[] selectionArgs) {
72 | int code = mUriMatcher.match(uri);
73 | if (code == ACCOUNT) {
74 | SQLiteDatabase db = helper.getWritableDatabase();
75 | int result = db.update("account", values, selection, selectionArgs);
76 | db.close();
77 | return result;
78 | } else {
79 | throw new IllegalArgumentException("根据法律规定,你无权修改数据。");
80 | }
81 | }
82 |
83 | - 查
84 |
85 | public Cursor query(Uri uri, String[] projection, String selection,
86 | String[] selectionArgs, String sortOrder) {
87 | int code = mUriMatcher.match(uri);
88 | if (code == ACCOUNT) {
89 | SQLiteDatabase db = helper.getReadableDatabase();
90 | Cursor cursor = db.query("account", columns, selection,
91 | selectionArgs, null, null, null);
92 | return cursor;
93 | } else {
94 | throw new IllegalArgumentException("根据法律规定,你无权查看数据。");
95 | }
96 | }
97 |
98 | ##05 学习内容提供者的目的?
99 | 1. 要能看懂内容提供者的源码,别人是怎么通过内容提供者把数据暴露出去的,
100 | 要怎么去调用别人暴露的数据。
101 |
102 | 2. 应用场景:常见的应用-短信、通讯录联系人
103 |
104 | ##06 短信的内容提供者Uri和短信表结构
105 | - 系统短信的内容提供者路径:content://sms/
106 |
107 | - 分析mmssms.db数据库短信sms表结构:
108 | 列:address 电话号码,date 发送或接收的时间,type 2表示发送,1表示接收,body 短信内容.
109 |
110 | ##07 短信的备份 (重要)
111 |
112 | 1. 通过短信的内容提供者把短信数据查询出来
113 | 2. 把短信以xml文件的格式写到SD卡
114 |
115 | 在清单文件中添加权限:
116 |
117 |
118 |
119 |
120 |
121 | ##08 短信的还原 (重要)
122 | 1. 解析SD卡上xml格式的短信
123 | 2. 通过短信内容提供者向数据库中插入短信记录
124 |
125 | 在清单文件中添加权限:
126 |
127 |
128 |
129 |
130 | ##09 通讯录数据库的表结构
131 |
132 | 1. raw_contacts 联系人表
133 | 保存联系人的id contact_id
134 |
135 | 2. data 数据表
136 | 保存联系人的数据
137 |
138 | 3. mimetypes
139 | MIME数据类型表
140 |
141 | ##10 如何获取系统联系人信息?(重要)
142 |
143 | 1. 查询raw_contacts表中的 _id(联系人的主键)
144 | Uri: content://com.android.contacts/raw_contacts/
145 | 字段: contact_id
146 |
147 | 2. 根据联系人ID在data表中查询联系人的记录
148 | Uri: content://com.android.contacts/data/
149 | 字段: mimetype_id,raw_contact_id,data1;
150 | 注意查询的列中,mimetype_id需要改成mimetype;
151 |
152 | 3. 根据mimetype判断当前记录是联系人的姓名,电话,email
153 |
154 | ##11 插入联系人到通讯录 (重要)
155 |
156 | 通过联系人的内容提供者向联系人数据库中插入一个联系人记录
157 |
158 | 1. 先在raw_contacts表创建一个新的id
159 | 2. 在data表里面添加这个id对应的数据,电话、姓名、email等
160 |
161 | ##12 内容观察者
162 | 不属于四大组件,只是内容提供者对应的一个小功能
163 |
164 | 应用场景:用来观察内容提供者数据的变化情况的
165 |
166 | ##13 短信窃听器
167 | 通过内容观察者窃听用户发出短信时,查询短信数据库
168 |
--------------------------------------------------------------------------------
/第六天_Activity页面跳转和数据传递_.md:
--------------------------------------------------------------------------------
1 |
2 | #Activity界面跳转、数据传递和生命周期
3 |
4 | #Android中四大组件
5 | - Activity 活动界面
6 |
7 | - BroadcastReceiver 广播接收者
8 |
9 | - Service 服务
10 |
11 | - ContentProvider 内容提供者
12 |
13 | ##01 AndroidManifest清单文件详解
14 |
15 | 1.一个应用程序可以有多个桌面图标
16 |
17 | 2.创建桌面图标的方法如下:
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | 3.activity节点中的label标签表示桌面图标的名称
27 |
28 | 4.activity节点中的label标签表示界面的标题或者名称
29 |
30 | 5.application节点中的label标签与activity节点中的label标签不是一个概念,它表示应用程序的名称,可以在应用程序管理列表中看到
31 |
32 | category:BROWSABLE浏览器类型,CAR_MODE 驾驶模式;DEFAULT默认类型,通常自己写的activity都是用这个类型;
33 |
34 | ##02 意图设置动作激活一个新的界面(重点)
35 |
36 | 1. 初始化意图 (做一件事情的目的)
37 |
38 | 2. 设置动作(在清单文件中配置的action)
39 |
40 | intent.setAction("cn.itcast.multiview.SECONDACTIVITY");
41 |
42 | 3. 设置数据(在清单文件中配置的data)
43 |
44 | intent.setData(Uri.parse("itcast://dfds"));
45 |
46 | 4. 添加类型(在清单文件中配置的category)
47 |
48 | intent.addCategory("android.intent.category.DEFAULT");
49 |
50 | 5. 打开页面(打开第二个界面)
51 |
52 | startActivity(intent);
53 |
54 | ##03 设计意图的目的?
55 | - 作用:激活组件和传递参数
56 |
57 | - 目的:组件之间解耦
58 |
59 | 解耦:要求写的两个程序之间可以相互独立,又可以相互调用;
60 |
61 | ##04 意图的分类:隐式意图和显式意图(重点)
62 | 1. 隐式意图:在开启目标activity时,系统通过一组动作、数据、类别等属性去清单文件里面匹配,如果匹配到,就打开目标actvity,如果没有匹配到,就抛出异常,没有找个这个activity
63 |
64 | 应用场景:适合开启其他应用程序中的activity
65 | 缺点:速度慢,效率低
66 |
67 | 2. 显式意图:在开启目标activity时,直接指定activity的名称。
68 |
69 | 步骤:
70 | 1. 初始化意图 ,指定要打开activity的名称SecondActivity
71 | Intent intent = new Intent(this, SecondActivity.class);
72 | 2. 打开目标activity
73 | startActivity(intent);
74 |
75 | 应用场景:适合开启本应用程序中的activity;
76 | 优点: 速度快,效率高,代码书写简单
77 |
78 |
79 | ##05 意图传递数据(重点)
80 |
81 | 1. 基本数据类型及其数组
82 |
83 | 2. parcelable:把对象序列化到内存中
84 |
85 | 3. serializable:把对象序列化到文件中
86 |
87 | 4. bundle:类似于map的集合
88 |
89 | 5. intent:意图
90 |
91 | ##06 URI介绍
92 | http://www.baidu.com:80/img/bd_logo1.png
93 |
94 | 组成结构:
95 | 1.schema:简单的理解为是协议名称,如http
96 |
97 | 2.host:主机名,如192.168.1.100或者ip
98 |
99 | 3.port:端口号,如8080
100 |
101 | 4.path:路径,如image文件夹
102 |
103 | 5.数据:数据资源,如1.jpg
104 |
105 | ##07 开启activity获取返回值(重点)
106 | 第一个界面跳转到第二个界面,等待第二个界面关闭时,返回给第一个界面数据
107 |
108 | 1. 采用一种特殊的方式开启Activity
109 | startActivityForResult(intent, 0);
110 | 2. 在开启的第二个Activity里面设置数据
111 | Intent data = new Intent();
112 | data.putExtra("content", content);
113 | setResult(0, data);
114 | 3. 记得关闭新开启的第二个activity
115 | finish();
116 | 4. 在第一个Activity里面,重写一个方法,获取返回的数据
117 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
118 | //data就是返回的intent,里面包含有数据
119 | }
120 |
121 | ##08 请求码和结果码的作用(重点)
122 | - 请求码的作用:
123 |
124 | 用来判断当前数据是从哪个界面返回的
125 |
126 | - 结果码的作用:
127 |
128 | 用来判断当前数据是从哪个界面返回的
129 |
130 | ##09 activity的生命周期(重点)
131 |
132 | - 打开一个activity调用的方法:onCreate(),onStart(),onResume()
133 |
134 | - 关闭一个activity调用的方法: onPause(),onStop(),onDestroy()
135 |
136 | - 最小化一个activity调用的方法:onPause(),onStop()
137 |
138 | - 打开一个最小化的activity调用的方法:onRestart(),onStart(),onResume()
139 |
140 | ##10 读文档查看activity的生命周期的分类
141 |
142 | 1. entire lifetime(完整的生命周期方法):
143 |
144 | onCreate(),onStart(),onResume(),onPause(),onStop(),onDestory()
145 |
146 | 2. visible lifetime(可视的生命周期方法):
147 |
148 | onStart(),onResume(),onPause(),onStop()
149 |
150 | 3. foreground lifetime(前台生命周期方法):
151 |
152 | onResume(),onPause()
153 |
154 | ##11 横竖屏切换activity的生命周期
155 | 1. 横竖屏切换生命周期的变化:
156 |
157 | 先关闭前一个界面,再打开一个新的界面
158 |
159 | 3. 固定Activity朝向
160 |
161 | android:screenOrientation="landscape"
162 | portrait:竖向的 landscape:横向的 sensor传感器类型(自适应)
163 |
164 | 3. 当屏幕朝向变化时,使actvity不敏感变化
165 |
166 | android:configChanges="orientation|screenSize|keyboardHidden"
167 |
168 | ##12 任务栈的概念
169 |
170 | - 任务:做的一件事情,activity的实例对象
171 |
172 | - 栈 :后进先出(吃完了吐出来) 队列:先进先出(吃完了拉出来)
173 |
174 | - 任务栈:task stack 记录用户操作的行为,维护一个用户体验。打开关闭的界面
175 |
176 | ##13 Activity的启动模式
177 |
178 | 1. standard:标准默认模式
179 |
180 | 打开应用的时,系统会给它创建一个默认的任务栈。开启新的activity,
181 | 系统会把这个activity压入到任务栈的栈顶,返回退出activity,系统会把activity移除任务栈。
182 |
183 | 应用:绝大多数默认的情况
184 |
185 | 2. singleTop:单一顶部模式
186 |
187 | 打开activity时,系统回去任务栈的顶部查找,如果栈顶是当前activity,系统就不会创建新的activity,而是使用已经打开的activity。
188 |
189 | 应用:浏览器书签,一个界面避免重复开启很多次
190 |
191 | 3. singleTask:单一任务模式
192 |
193 | 打开界面创建实例,系统会去整个任务栈查找,有没有当前的任务?如果没有,则在栈顶创建一个实例任务,
194 | 如果有,则删除当前实例任务上面的所有任务,使其位于栈顶,整个任务栈只有一个实例存在。
195 |
196 | 应用:浏览器
197 |
198 | 4. singleInstance:单一实例模式
199 |
200 | 前面三种都是在应用程序默认的任务栈里面。
201 | 系统会为它单独创建一个任务栈,在单独的任务栈里面运行.
202 |
203 | 应用:电话拨号器的通话界面
204 |
205 |
206 |
207 |
208 |
209 |
210 |
--------------------------------------------------------------------------------
/第三天_数据存储和界面展现.md:
--------------------------------------------------------------------------------
1 |
2 | ##数据的存储和界面展现
3 | 数据库、ListView
4 |
5 |
6 | #数据库
7 | -----
8 | ###1 Android数据存储的方式(重要)
9 | 1. Internal Storage 内部存储
10 | - cache
11 | - files
12 | 2. External Storage 外部存储SD卡
13 | - SD卡
14 | 3. SharedPreference 参数
15 | - 设置信息,配置信息,密码
16 |
17 | 4. SQLite Databases数据库
18 | - 相似结构的数据,大量存储,增删改查。
19 | - Sqlite
20 | 5. Network Connection网络存储
21 |
22 | ###2 Sqlite数据库
23 | - 开源的
24 | - 嵌入式的数据库,轻量级。
25 | - sql语句的增删改查和MySql语句差不多
26 |
27 | ###3 数据库的创建
28 | - java中文件的创建
29 |
30 | 1.在内存中,创建文件对象
31 | File file = new File("haha.txt");
32 | 2.在硬盘上,创建文件
33 | FileOutputStream fos = new FileOutputStream(file);
34 | fos.write("".getBytes());
35 | fos.close();
36 |
37 | - 数据库的创建
38 |
39 | 1.在内存中,创建数据库对象
40 | MyDBOpenHelper helper = new MyDBOpenHelper(this);
41 | 2.在手机里,创建数据库文件
42 | helper.getWritableDatabase();
43 |
44 |
45 | 数据库的存储路径: /data/data/包名/databases/
46 |
47 | ###4 数据库的操作
48 | - 增
49 | insert into stu (name,num) values ('zhangsan','1001')
50 | - 删
51 | delete from stu where _id = 1
52 | - 改
53 | update stu set name = 'lisi' where name = 'zhangsan'
54 | - 查
55 | select * from stu where _id = 1
56 |
57 | 优点:多表操作
58 | 缺点:容易出错并且没有返回值
59 |
60 | ###5 Android API对数据库表的增删改查(推荐使用)(重要)
61 | 缺点:单表操作
62 | 优点:不容易出错,有返回值
63 |
64 | - 增
65 |
66 | public void insert(View v) {
67 | // 1. 在内存中创建一个数据库帮助类的对象
68 | MyDbOpenHelper helper = new MyDbOpenHelper(this);
69 | // 2. 在手机上生成数据库文件
70 | SQLiteDatabase db = helper.getWritableDatabase();
71 | // db.execSQL("insert into stu (name,num) values (?,?)", new Object[] {
72 | // "linqingxia", 28 });
73 |
74 | ContentValues values = new ContentValues();
75 | values.put("name", "zhangsan");
76 | values.put("num", "10086");
77 | /*
78 | * table :表名 nullColumnHack:默认会添加一个NULL,一般写个null就行了 values
79 | * :ContentValues类似map集合
80 | */
81 | long res = db.insert("stu", null, values);
82 | if (res != -1) {
83 | Toast.makeText(this, "插入成功 :" + res, 0).show();
84 | } else {
85 | Toast.makeText(this, "插入失败 :" + res, 0).show();
86 | }
87 | // 重要,释放资源
88 | db.close();
89 | }
90 | - 删
91 |
92 | public void delete(View v) {
93 | // 1. 在内存中创建一个数据库帮助类的对象
94 | MyDbOpenHelper helper = new MyDbOpenHelper(this);
95 | // 2. 在手机上生成数据库文件
96 | SQLiteDatabase db = helper.getWritableDatabase();
97 | // db.execSQL("delete from stu");
98 | /*
99 | * table :表名 whereClause:where条件 whereArgs:查询参数
100 | */
101 | int res = db.delete("stu", null, null);
102 | if (res > 0) {
103 | Toast.makeText(this, "succ:"+res, Toast.LENGTH_SHORT).show();
104 | } else {
105 | Toast.makeText(this, "err", Toast.LENGTH_SHORT).show();
106 | }
107 |
108 | // 重要,释放资源
109 | db.close();
110 | }
111 | - 改
112 |
113 | public void update(View v) {
114 | // 1. 在内存中创建一个数据库帮助类的对象
115 | MyDbOpenHelper helper = new MyDbOpenHelper(this);
116 | // 2. 在手机上生成数据库文件
117 | SQLiteDatabase db = helper.getWritableDatabase();
118 | // db.execSQL("update stu set name=?", new Object[] { "yadan" });
119 | /*
120 | * table :表名 values :ContentValues类似map集合 whereClause:where条件
121 | * whereArgs:查询参数
122 | */
123 | ContentValues values = new ContentValues();
124 | values.put("name", "lisi");
125 |
126 | int res = db.update("stu", values, null, null);
127 | if (res > 0) {
128 | Toast.makeText(this, "succ:"+res, Toast.LENGTH_SHORT).show();
129 | } else {
130 | Toast.makeText(this, "err", Toast.LENGTH_SHORT).show();
131 | }
132 | // 重要,释放资源
133 | db.close();
134 | }
135 | - 查
136 |
137 | public void query(View v) {
138 | // 1. 在内存中创建一个数据库帮助类的对象
139 | MyDbOpenHelper helper = new MyDbOpenHelper(this);
140 | // 2. 在手机上生成数据库文件
141 | SQLiteDatabase db = helper.getReadableDatabase();
142 |
143 | Cursor cursor = db.rawQuery("select * from stu", null);
144 | /*
145 | * table :表名
146 | * columns :要查询的列
147 | * selection:查询条件
148 | * selectionArgs:查询参数
149 | * groupBy :分组
150 | * having :条件
151 | * orderBy :排序
152 | * limit :限制条件
153 | *
154 | */
155 | Cursor cursor = db.query("stu", new String[]{"num","name","_id"}, null, null, null, null, null, null);
156 | while (cursor.moveToNext()) {
157 | int id = cursor.getInt(2);
158 | String name = cursor.getString(1);
159 | String num = cursor.getString(0);
160 |
161 | System.out.println("======");
162 | System.out.println("id:" + id + " name:" + name + " num:" + num);
163 | }
164 |
165 | // 重要,释放资源
166 | cursor.close();
167 | db.close();
168 | }
169 |
170 |
171 |
172 | #ListView
173 | -----
174 | ###6 ListView
175 |
176 | - 应用场景:用于显示大量结构相似的数据
177 |
178 | - 优化:复用converView
179 |
180 | ###7 Android中常见的默认实现类
181 | * BaseXXX
182 | * BasicXXX
183 | * SimpleXXX
184 | * DefaultXXX
185 |
186 | ###8 ListView的编写步骤(重要)
187 | 1. 在xml布局文件中声明listview的控件
188 |
189 |
193 | 2. 在代码里面查找listview
194 |
195 | findViewById(R.id.lv);
196 | 3. 设置listview的数据适配器
197 |
198 | lv.setAdapter(new MyAdapter());
199 | 4. 编写数据适配器
200 |
201 | private class MyAdapter extends BaseAdapter{
202 | public int getCount() {
203 | return ...;//告诉listview里面有多少条数据
204 | }
205 | public View getView(int position, View convertView, ViewGroup parent) {
206 | return ...;//返回每个位置显示的view是什么样子的。
207 | }
208 | }
209 |
210 |
211 | ###9 常见的数据适配器
212 | - ArrayAdapter 数组适配器
213 |
--------------------------------------------------------------------------------
/第七天_广播与服务.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | #广播接收者
4 | 1. 什么是广播?
5 | - 电台:对外发送信号。
6 | - 收音机:接收电台的信号。
7 |
8 | 2. 为什么要用广播接收者?
9 |
10 | 在Android操作系统中也有一个类似广播电台的功能,可以把公用的一些事件作为广播消息发送出去.每个应用程序都可以接收这个事件。
11 |
12 | 3. Android系统中常见的广播事件
13 |
14 | 电池电量低,SD卡被移除,有电话打出去,有短信发送进来,软件的卸载安装,手机锁屏解锁,开机启动。
15 |
16 | ##01 android广播接收者编写步骤
17 | 1. 买收音机
18 |
19 | 2. 装电池
20 |
21 | 3. 调频道,调到你关心的频道
22 |
23 | ##02 广播接收者案例 SD卡状态监听(重点)
24 |
25 | 清单文件中需要配置如下:
26 |
27 | SD卡插拔动作:
28 |
29 |
30 |
31 | 数据类型,如果不配置,接受不到广播
32 |
33 |
34 | ##03 广播接收者案例 ip拨号器(重点)
35 | - 需求:当拨打长途电话时会自动的在电话号码前面添加17951;
36 |
37 | - 原理:通过网络拨打本地电话
38 |
39 | - 编写步骤:
40 |
41 | 1.买一个收音机:
42 | public class IpCallBroadcastReceiver extends BroadcastReceiver{}
43 | 2.装电池:
44 |
45 | 3.调整一个频道接收广播:
46 | 外拨电话的广播事件
47 |
48 | 4.添加权限:
49 |
50 |
51 | ##04 广播接收者案例 短信窃听器(重点)
52 |
53 | - 编写步骤:
54 |
55 | 1.写一个广播接收者,用于接受短信到来事件
56 | pdus:protocol data unit s 协议数据单元;
57 | 2.取出短信数据
58 | 3.转发短信到自己的手机
59 |
60 | - 清单文件中配置:
61 |
62 | 接收和发送短信权限:
63 |
64 |
65 |
66 | 短信到来动作:
67 |
68 |
69 | ##05 广播接收者案例 应用的卸载安装(重点)
70 |
71 | 清单文件中需要配置如下:
72 |
73 |
74 |
75 | //覆盖安装
76 |
77 |
78 | 数据,必须添加这个属性,否则接收不到这些事件
79 |
80 |
81 | ##06 广播接收者的特点和版本差异
82 |
83 | 1. 即使广播接收者没有运行,当广播事件到达的时候,系统会自动开启广播接收者,并且调用onReceive方法处理消息
84 |
85 | 2. google出于安全上的设计,强制要求4.0之后的版本,广播接收者如果被手工强制停止掉,就不能够接收到广播事件了,只有在下次启动这个广播接收者的程序后才能接收到广播事件
86 |
87 | ##07 自定义广播接收者的发送和接受
88 | - 搭建电台:
89 |
90 | 1.创建一个意图对象用于激活广播接收者和给接收者传递数据
91 | Intent intent = new Intent();
92 | 2.设置广播的事件的动作
93 | intent.setAction("cn.itcast.CUSTOMBROADCAST")
94 | 3.设置给接收者传递的数据
95 | intent.setData(Uri.parse("itcast://打瓶酱油"))
96 | 4.发送广播
97 | sendBroadcast(intent);
98 |
99 | - 自定义广播接收者:
100 |
101 | 1. 买收音机
102 | 2. 装电池
103 | 3. 调频道,调到你关心的频道
104 |
105 | ##08 有序广播和无序广播(重点)
106 | 1. 无序广播:广播消息发送出去后,只要是指定这个事件的接收者都可以接收到这个事件
107 | - 无序广播的消息不能被拦截.不能被修改
108 |
109 | 2. 有序广播:广播消息发送出去后,按照接收者的优先级,从高到低一级一级的接受消息
110 |
111 | - 高优先级的接受者可以把广播消息给拦截,还可以修改广播的数据。
112 |
113 | - 如果没有给接收者指定优先级,会按照清单文件中接收者配置的先后顺序接受消息;放在最前面的接收者最先接收到消息,放在最后面的接收者后接收到消息
114 |
115 | - 有序广播可以指定最后一个接收者,他不在清单文件中注册,可以查看广播最终的数据
116 |
117 | ##09 两种广播的不同之处:
118 | - 如果拦截无序广播,会拦截失败
119 | - 无序广播不可以修改数据
120 |
121 | ##10 广播接收者案例 锁屏解锁(重点)
122 |
123 | 用代码注册 频繁生成事件的广播接受者
124 | IntentFilter filter = new IntentFilter();
125 | filter.addAction("android.intent.action.SCREEN_OFF");
126 | filter.addAction("android.intent.action.SCREEN_ON");
127 | ScreenReceiver receiver = new ScreenReceiver();
128 | this.registerReceiver(receiver, filter);
129 |
130 | 重要,注销锁屏广播
131 | unregisterReceiver(receiver)
132 |
133 | ##11 广播接收者案例 开机启动(重点)
134 |
135 | 清单文件中需要配置如下:
136 | 开机完成权限:
137 |
138 |
139 | 开机完成动作:
140 |
141 |
142 | 代码:
143 | 记得告诉Activity可以运行在应用程序的任务栈里面
144 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
145 |
146 | # 服务 service
147 |
148 | ##01 线程进程和应用程序之间的关系
149 |
150 | 开启应用程序Android系统为其创建一个Linux进程,应用程序的所有组件都是运行在同一个进程的同一个线程(main)里面。
151 |
152 | - 应用程序:包含了四大组件中任何一个或者多个组件的程序
153 |
154 | - 进程:应用程序的载体。主要用来负责运行dalvik虚拟机,而我们开发的应用程序就是运行在dalvik虚拟机里。
155 |
156 | - 进程销毁,进程里面的所有线程都不存在了
157 |
158 | ##02 进程的生命周期及其优先级
159 | - Process lifecycle 进程的生命周期
160 |
161 | - Android操作系统会尽可能长期的保留应用程序的进程,系统根据进程的优先级回收不重要的进程,释放内存。
162 | - 如果进程被系统回收,开启的所有的线程都不在了。
163 |
164 | - 进程的优先级:
165 |
166 | 1. Foreground process 前台进程
167 | 能看到应用程序的界面。并且可以操作这个应用程序。
168 | 2. Visible process 可视进程
169 | 能看到这个应用程序,但是操作不了。
170 | 3. Service process 服务进程
171 | 应用程序带一个后台运行的服务,并且服务没有停止。
172 | 4. Background process 后台进程
173 | 应用程序被最小化了,但是没有退出。
174 | 5. Empty process 空进程
175 | 应用程序没有任何活动的组件了
176 |
177 | ##03 服务
178 |
179 | 1. 什么是服务?
180 |
181 | 是一个没有界面,并且可以长期运行在后台的组件(简单的理解为是没有界面的activity)
182 |
183 | 2. 为什么要用服务?
184 | - 问题:如果开启子线程,也可以没有界面,长期后台运行。
185 |
186 | 让线程长期运行在后台,如果进程被系统回收,开启的所有的线程都不在了
187 | - 内存不足时,系统杀掉服务,如果内存充足,系统会还原服务
188 |
189 | 3. 服务编写步骤:
190 |
191 | 1.自定义一个类,继承父类Service;
192 | 2.在清单文件中配置一个service节点,name属性指向这个类的名称;
193 |
194 | ##04 服务的生命周期(重点)
195 |
196 | - 生命周期方法:
197 |
198 | 1.onCreate:在服务对象创建后调用这个方法,初始化服务对象;
199 | 2.onStartCommand:开启服务后调用这个方法;
200 | 3.onDestroy:在服务对象被销毁之前调用这个方法,通常在这个方法中做一些扫尾工作,比如保存数据;
201 |
202 | - 特点:
203 |
204 | 1. start方式第一次开启服务时,先创建服务对象,然后再开启服务
205 | 调用方法:onCreate(),onStartCommand()
206 | 2. 服务可以被多次开启,每次开启时只调用
207 | onStartCommand() (onStart已过时)
208 | 3. 服务只能被停止一次,调用方法:onDestroy()
209 | 如果服务已经停止,多次调用stopService()无效
210 |
211 | ##05 服务里面可以执行耗时的操作吗?(面试题)
212 |
213 | - 服务是运行在主线程(main ui线程)里面的,不可以执行耗时的操作
214 |
215 | - 如果要执行耗时的操作需要在服务里面开启子线程执行耗时的操作。
216 |
217 | - 服务的特点:就是保证当前应用程序不容易被系统回收,即使被回收还会复活。
218 |
219 | ##06 监听电话状态的模板代码(重点)
220 |
221 | 1. 清单文件中添加权限:
222 |
223 |
224 |
225 | 2. 代码:
226 |
227 | 1. 获取系统电话的服务
228 | TelephonyManager tm = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
229 | 2. 设置电话状态监听器
230 | tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
231 | 3. 创建内部类
232 | private class MyListener extends PhoneStateListener {
233 | // 当呼叫的状态发生变化调用的方法。
234 | @Override
235 | public void onCallStateChanged(int state, String incomingNumber) {
236 | System.out.println("来电号码:"+incomingNumber);
237 | // 零响 接通状态 空闲
238 | switch (state) {
239 | case TelephonyManager.CALL_STATE_IDLE: // 空闲
240 | break;
241 | case TelephonyManager.CALL_STATE_RINGING: // 响铃状态
242 | break;
243 | case TelephonyManager.CALL_STATE_OFFHOOK: //电话接通
244 | break;
245 | }
246 | super.onCallStateChanged(state, incomingNumber);
247 | }
248 | }
249 | 4. 服务停止的时候 取消监听全部的状态
250 | tm.listen(listener, PhoneStateListener.LISTEN_NONE);
251 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------