项目经历整理

This commit is contained in:
yinkanglong_lab
2021-04-06 23:30:37 +08:00
parent b845347c66
commit 30f583d779
54 changed files with 3246 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
Android studio中常见的使用技巧
1. 编辑器
折叠县、标记栏
alt+数字 启动工具窗口
window中可以修改restore layout
2. 导航工具栏
project工具栏能够选择不同的模式
structure工具栏查看xml和.java的文件结构
favorites收藏的文件、行、断点
TODO工具补充注释
Commander工具窗口
3.主菜单栏,实现大部分功能
4. 工具栏能够实现基本的文本编辑运行调试可以通过View|Toolbar菜单项的选中来隐藏工具栏
5. 导航栏,用来定位当前的位置。
6. 状态栏,在整个界面的最低端,主要包括消息去,光标位置,行分隔符区域,文本格式区域,文件访问标识符区域,如出现时级别按钮
7. 常用操作。
ctrl+a,ctrl+w,ctrl+z,ctrl+shift+z
ctrl+e查看最近的文件
ctrl+alt+方向箭头遍历导航操作。
ctrl+一般的字母实现cut、copy、paste扩展粘贴赋值路径赋值偏好。
8.上下文菜单
9. 获取帮助
10.使用键盘导航
alt+f1 selectin
ctrl+n class查找
ctrl+shift+n find file
ctrl+g find line
ctrl+alt+home related file
ctrl+shift+backspace last edit location
ctrl+h type hierarchy
ctrl+b declaration
11.查找和替换文本
ctrl+f
ctrl+shift+f
ctrl+r
ctrl+shift+r
第三章在Androidstudio中进行编程
1. helper中能够find action对Androidstudio中的界面和属性进行操作
ctrl++’折叠光标代码块
ctrl+-’展开光标代码块
ctrl+shift++’折叠所有代码块
ctrl+shift+-’站看所有代码块
ctrl+‘。’折叠展开代码块
2. 执行代码补全
方向箭头选择enter键使用
3. 代码注释
ctrl+/java行注释
ctrl+shift+/java筷箸史
4.使用代码生成工具
5.插入动态模板
6.移动代码
7.设计代码风格(这里都是些无关紧要的细枝末节,让我们来看其他的东西)
第四章代码重构
感觉也不是我现在应该看得东西
这本书怎么看都是给老鸟进阶用的,还是随便浏览一下,直接归还得了。
可恶git的学习时间可能又要拖一段了。另外如果有一天完成了当下所有的作业而且还有足够的心情时在去学习和使用这些新东西吧。

View File

@@ -0,0 +1,63 @@
# Android的HelloWorld级别的问题解决
--------------
## >附加知识补充
----
> 1. sdk manager管理Android开发环境和系统镜像的文件夹
2. avd manager管理Android虚拟设备的工具,我们自己创建的avd设备存放在.android的目录下面。
3. android device monitorAndroid的状态监视工具和控制台命令窗口
4. android debug bridgeadbAndroid的调试工具
----
>使用eclipse创建Android程序比Androidstudio困难n倍毕竟自己小白不懂一些原理所以导致helloworld小程序的各种难产。
## > Android创建过程中的版本问题
* 首先在高版本的Android sdk中提供了对低版本Android sdk的支持这种支持不是直接兼容低版本的东西而是通过支持库包来时线即Android Support Library package来保证高版本的sdk的向下兼容性也就是说让低版本的sdk能够运行高版本的功能。其中
V4 Support Library支持API4及更高版本的Android sdk
V7-----------------------7-----------------------
V9-----------------------9-----------------------
V13----------------------13----------------------
V17----------------------17----------------------
* 在libs的文件夹目录下会产生低版本兼容库Android-support-v4或者v7等这与你在创建工程时选择的最低兼容sdk版本有关。另外如果选择的编译版本较高时会产生一个单独的兼容文件夹并且会报错此错误网上有解决方法经测试没几个可行的
## >关于style.xml/AppTheme相关的问题
------
解决这个问题主要有三种方法,参考:
http://www.jianshu.com/p/6ad7864e005e
(给的原理说明十分清晰)
1. 将所有values下的styles.xml都改为同样的最基础版本的theme即baseTheme里的基本主题
2. 如果想使用最新的主题效果可以可以将AndroidManifest.xml里的minSdkVersion改成14及已经包含此主题的sdk
3. 如果想兼容更低版本并且支持新主题需要导入支持库即Android-support-v7-appcompat库下载完成后通过导入工程的方式将这个库导入到相应的文件当中。在libs目录下回有兼容库包。具体方法参考原网站
## >Android使用过程中图标的导入问题
------
android:icon="@drawable/bear"变量的值经常出错,在制定文件夹下面并没有对应的图标需要插入自己导入的图标然后修改这个变量的值。
## >关于Android启动模拟器失败的解决方法
--------
> Dx unsupported class file version 52.0
* 首先创建虚拟设备对应相应的sdk然后运行虚拟设备继续讲程序launch到虚拟设备当中其间出现这样的错误在其他网站上已经有比较详细的说明
这个问题主要的原因是依赖包的编译版本比主程序的编译版本高,导致主程序无法正常编译或运行,解决这个问题无非两招:
1. 提升主程序的编译器版本,用最新的编译器编译主程序,这样就可以兼容那个依赖包
2. 降低依赖包的编译版本。
具体方法参考:
http://blog.csdn.net/feijitouhaha/article/details/52141274

View File

@@ -0,0 +1,21 @@
# android总体知识总结
----
## Activity宏观的介绍
-----
* Activity是一个应用程序窗口本身不提供用户界面元素只提供UI组件摆放和依附的容器视图View在layout.xml中定义Activity.setContentView()方法将Activity于View建立关联。
* 布局管理器--导演
* Activity--舞台
* ViewUI控件--演员
* 生命周期的每个阶段都有自己的回调函数
* onCreate
* onStart
* onResume
* onRestrart
* onPause
* onStop
* onDestroy
*

View File

@@ -0,0 +1,40 @@
# android的学习目录和索引
## 第一章
## 第二章
## 第三章
## 第四章
## 第五章
## 第六章
## 第七章
## 第八章
## 第九章
## 第十章
## 第十一章
##第十三章

View File

@@ -0,0 +1,16 @@
# Service
## 与service相关的方法和类总结
* Service
* IBinder onBinder(intent intent)通过该对象IBinder与service进行通信

View File

@@ -0,0 +1 @@
asf

View File

@@ -0,0 +1,46 @@
# 第一章基础知识讲解
-----
## >Android系统简介
-----
* **android 分层**
1. 应用程序层
2. 应用程序框架层
3. 系统运行库
4. linux核心层。
* **设计规则**
1. 每个程序都运行在了自己的进程空间中,需要时启动,不需要时终止。
2. 每个程序都有自己的运行库ART各应用程序之间的代码是相互隔离的。
3. 每个程序被分配唯一的ID任何应用程序的代码与其他应用程序的代码是相互隔离的。
* **Android应用程序的四大组件**
1. activity活动用于与用户进行交互的可视化界面凡是在应用程序中看到的东西都是放在activity中。每一个activity子类集成父类Activity。
2. Service服务无需可视化界面需要在后台长期运行的应用程序背景音乐播放器和后台数据处理任务等继承自父类Service。
3. Broadcast Receiver广播接收器接受和处理广播消息的组件。没有影虎界面在相应其接收到的信息时可以启动一个activity继承自父类BroadcastReceiver。
4. Content Provider内容提供者可以将指定的一组数据让其他程序使用。数据可能存储在文件系统或者SQLlife中。继承自父类ContentProvider。
5. 补充Intent负责对应一次操作中的动作、动作涉及的数据、附加数据进行描述。Android根据此描述找到对应的组件将intent传递给调用的组件。
* **Android应用程序框架层**
1. 使用java语言编写。
2. 使用java native interface调用core lib层的本地方法
3. 实现了一系列服务活动管理器窗口管理器、内容提供器、视图系统、通告管理器、包管理器、电话管理器、资源管理器、位置管理器、xmpp服务。
* **系统运行库**
1. 系统C库 从BSD集成的标准C系统函数库
2. 媒体库基于OpenMax库支持多种音频视频图像文件
3. Serface Manager显示子系统管理提供了2D&3D图层的无缝融合
4. LibWebCore最新的web浏览器引擎。
5. SGL底层的2D图形引擎
6. 3Dlibraries基于OpenGL3D软件加速
7. FreeType文图和矢量图字体显示
8. SQLLite数据库引擎。
9. Dalvik虚拟机在程序执行时编译成dex的字节码后交给dalvik虚拟机执行
10. ART虚拟机Dalvik的替代品。在应用成许安装时吧程序代码转换成及其语言避让程序成为真正的本地应用。
- 采用了AOT预编译技术。函数调用去虚拟化调用接口和虚函数时需要寻找真正的函数浪费大量的时间。去虚拟化后可以迅速调用。消除异常检查。
- 更高效的垃圾回收机制GC。GC调用有三种情况GC_EXPLICIT应用程序通过system.gc主动调用GC_FOR_ALLOC内存分配不足时 GC_CONCURRENT给java层分配内存后计算一份陪的大小达到阈值时对象大小超过384KBGC_MALLOC(内存分配失败)GC_EXTERANL_ALLOC(外部内存分配失败)
* **Linux内核**
安全性、内存管理、进程管理、网络协议栈、驱动模型。

View File

@@ -0,0 +1,41 @@
# android的helloworld
---------
## >androidStudio的开发步骤
-----
1. 创建android项目和文件结构
2. 在XML布局文件中定义应用程序的用户界面
3. 在.java文件中编写业务的实现。
> android 的文件结构中只有三个有用:.java实现应用程序的业务res中的.xml实现工程的视图的资源文件manifest.xml实现相关资源的协调配置。
> 4大组件activityservicebroadcastreceivercontentProviderintent不同组件之间通讯的载体
## >android studio 中的文件结构
* src文件夹保存java文件
* res文件夹保存资源文件和xml文件
* bin文件夹存放生成的目标文件
* gen文件夹自动生成的R.java文件
## >相关文件的理解
-----
* R.java是一个资源统筹文件每个资源对应一个内部类的int值和field相当于为为每个其他的资源文件添加了一个变量或者说定义了一个相对于软件的全局变量。在.java文件中相当于添加了一个字段public static final int app_name = 00123031;在xml文件中的引用方法@string/app_name另外标识符不需要R资源文件的定义就可以直接使用@+id/ok
* value/string.xml,定义了全局的字符串常量。
* androidManifest.xml全局描述文件。统筹了很多东西。通过<manifest/>标签声明需要的权限,<activity/>声明被调用用的权限。
## &gt;antivity中包含的方法的总结
-----
getWindow()获得当前窗口的对话框
setContentView()设置当前activity的主要视图xml文件
setTheme()设置xml文件显示的主题风格
签名防止同名的包中的程序被覆盖。

View File

@@ -0,0 +1,16 @@
## 第二章界面编程Dialog
-----
# &gt;对话框
-----
* AlertDialog
1. 组成:包括图标区、标题区、内容区、按钮区
2. 使用步骤:定义对象->设定标题->设定图标->设定对话框的内容->设置按钮->创建对象
3. 相关方法setTitle();setCustomTitle();setIcon();setPositiveButton();setNegativeButton;setNeutralButton();setMessage();setItems();setSingelChoiceItems();setAdapter();setView()
> 遇到的问题:
> android:theme="@android:style/Theme.Material.Dialog.Alert在manifest.xml中修改视图的主题失败导致软件不能启动
> View root = this.getLayoutInflater().inflate(R.layout.popup,null);这句话的具体意图没有搞明白,似乎是把某个视图声明为子视图。

View File

@@ -0,0 +1,15 @@
# 第二章界面编程view组件的应用
----
# &gt;view组件
----
> 对于属性和相关方法的理解其中每一个空间都是一个对象每个对象都有指定的属性和方法。在xml可以定义一个对象并通过xml的语法格式对创建的对象的属性进行初始化同样也可以在java中使用public方法对相关的对象进行属性的设置。
> 另外可以在xml使用对象的布局也可以通过java对布局进行设定。
* 属性和相关方法
> 事实证明刚才犯了一个及其傻逼的错误在对android极其不了解的情况下认为同一个页面可以使用多个布局极其傻逼浪费了自己大量时间不过也让自己静下心来认真的读了一点点代码。

View File

@@ -0,0 +1,119 @@
# Android第三章
----
## &gt;事件处理的概述
----
* 两种事件处理机制
1. 基于监听的事件处理
2. 基于回调的事件处理
## &gt;基于监听的事件处理机制
----
* 涉及到的三类对象
1. Event Source事件源指各个组件。
2. Event 界面组件上发生的特定的事情,。
3. Event Listener监听事件源发生的事情。并对各种事情作出相应的响应。
4. Event Handler事件处理器当事件监听器捕获事件后由响应的事件处理器识别特定的事件并做出响应的动作。
* 事件监听机制的工作流程
普通组件(事件源对象) 发生很多事件,生成多种事件对象 被同一个监听器对象捕获 监听器通过不同的事件处理器处理这个事件。
> 每个组件可以根据不同的事件类别指定多个监听器,每一个监听器可以监听多个事件源。
## &gt;实现事件监听器的方法
----
1. 内部类作为时间的监听器
使用内部类作为事件监听器能够在这个类内复用该监听器。该监听器类能够自由访问外部类的所有界面组件
2. 外部类作为时间监听器
事件监听器通常属于特定的GUI界面定义成外部类不利于提高程序的内聚性。外部类形式的时间监听器不能够自由访问GUI界面的类中的组件。同时也适用于监听器于GUI界面没有任何耦合情况。
> 监听器还是主要来写显示逻辑,具体的业务逻辑放到外部的其他函数或者类中进行处理。
3. Activity类本身作为事件监听器
不推荐activity类本身用来界面初始化工作包含事件监听器容易造成程序的逻辑结构混乱。
4. 匿名类作为时间监听器类
大部分时候事件监听器类的代码没有什么复用价值,所以只要使用匿名类来实现事件监听器想要达到的页面逻辑就好。
> android可以直接在界面布局中制定标签绑定事件的处理方式。
> androidonClick="clickHandler"
## &gt;基于回调的事件处理方法
----
* 回调机制
事件的处理直接绑定到与组件相关的时间处理函数上,而非通过监听器的监听和事件处理器的匹配处理。有点像事件监听器和事件源融合在一起,不需要单独的时间监听器类,事件源本身能够监听自身发生的各种事件。
* 基于回调的事件传播
当返回为true时表明该方法已经能够处理发生的事件事件不会向外传播给外层的时间监听器。当返回为false时如果有外围的监听器处理同一个事件则事件会向外传播同时被其他监听器坚挺到。如果存在各种监听器其监听顺序为绑定的事件监听器-->基于回调的内部事件监听器-->基于回调的外部事件监听器。
## &gt;相应系统设置的事件
----
* 用来获取系统的配置
```Configuration cfg = getResources().getConfiguration();
```
* onConfigurationChanged能够监听相关的配置改变的事件。
## &gt;Handler消息传递机制
---
* 工作原理
android第一次启动主线程负责activityUI界面的线程而且只允许UI线程对主界面进行修改其他新启动的线程无法对主界面进行直接修改需要使用Handler进行消息传递。
* Handler简介
1. 在新启动的线程中发送消息
2. 在主线程中获取和处理消息
>好像是原来的事件处理机制变成了消息处理机制,通过监听消息,处理消息完成一系列动作,同事件处理一样。
* Handler涉及的方法
1. HandlerMessage()
2. hasMessage()
3. hasMessages()
4. obtainMessage()
5. sendEmptyMessage()
6. sendEmptyMessageDelayed()
7. sendMessage()
8. sendMessageDelayed()
* Handler、Loop、MessageQueue的工作原理
1. Message是Handler接受和处理的对象
2. Looper每个线程只能有一个Looperloop方法负责读取MessageQueue中的消息
3. MessageQueen消息队列采用了先进先出的方式管理队列。
```
private Looper()
{
mQueue = new MessageQueue();
mRun = true;
mThread = Thread.currentThread();
}
```
* Looper类的使用方法
1. 调用Looper的prepare方法创建Looper对象生成对应的MessageQueue来管理事件
2. 创建Handler子类用于发送本线程的消息。重写HandlerMessage方法负责处理来自其他线程的消息。
3. 调用Looper的loop方法启动Looper类
>UI线程一般专门用来相应用户的界面操作而其他的逻辑运算和处理都交给其他线程处理主要目的是防止UI线程被阻塞而让用户以为界面卡顿。
>此时如果UI线程与其他线程的交互方式就是Handler消息传递机制同事件监听机制的逻辑十分相似。
## &gt;异步任务
----
* 解决新线程不能更新UI主界面的问题的方法
* 使用Handler消息处理机制
* Activity.runOnUiThread(Runnable)
* View.post(Runnable)
* View.postDelayed(Runnable,long)
* 异步处理机制
* AsyncTask<Params,Progress,Result>异步类
1. 创建AsyncTask的子类并制定三个参数的类型。
2. 根据需要实现下列方法
* dolnBackground()后台线程即将执行的任务通过调用publishProgress()更新任务的执行进度
* onProgressUpdate()调用更新任务进度的方法后,会触发这个方法
* onPreExecute()方法,执行后台操作前被调用,完成初始化工作
* onPostExcute()后台任务执行完成后,调用这个方法
3. 调用AsyncTask子类的execute方法开始执行好事任务。

View File

@@ -0,0 +1,102 @@
4# 第四章Activity和Fragment2
----
## &gt;Activity的回调机制
----
* **回调机制的解释**
通用程序框架在完成整个应用个通用功能和流程时在特定点上需要相应的业务逻辑实现。java swing中的init()方法java Thread中的run方法都是一种回调机制
* **回调机制的存在形式**
1. 以接口的形式存在
2. 以抽象方法的形式存在通过oncreate、onActivityResult()函数能够直接创建一个Activity例如当有一个Activity被调用时生成相应的实例时就会通过onCreate方法创建一个Activity。
## &gt;Activity的生命周期
-----
* 四个状态
1. 运行状态当前Activity位于前台用户可见可以获得焦点。
2. 暂停状态其他Activity位于前台该activity依然可见但不能获得焦点
3. 停止状态该activity不可见失去焦点
4. 销毁状态activity结束。
* 生命周期示例图
![Activity的生命周期](http://img.my.csdn.net/uploads/201109/1/0_1314838777He6C.gif)
* Activity的四种加载模式
1. standard:标准模式
每次启动Activityandroid都会启动一个新的实例并通过Activity添加到当前的task栈顶就相当于同一个类会有多个对象同时在运行。
2. sigleTop:Task栈顶单例模式
与standard模式基本相同但是当要启动的类本身就位于栈顶事那么将不会重新创建Activity实例而是复用之前的Activity。
3. sigleTask:Task内单例模式
在同一个task中只允许有一种实例。不存在创建存在移动到栈顶显示。
4. sigleInstace:全局单利模式
无论从哪个任务中启动Activity都会只创建一个单一的实例。
> android 采用task栈对Activity进行管理先启动的放在 task栈底后启动的Activity被放在了task栈顶。
## &gt;Fragment详解
-----
* **Fragment的简介**
Fragment代表了Activity的子模块因此可以吧Fragment理解成Activity片段。Fragment拥有自己的生命周期能够接受自己的输入事件。
* Fragment总作为Activity的界面组成部分。Fragment可调用getActivity()方法返回ActivityActivity可以使用FragmentManager来管理相应的Fragment
* Fragment的add(),remove(),replace()方法可以动态地添加、删除或者替换Fragment。
* 一个Activity可以痛死组合多个Fragment一个Fragment 也可以被多个Activity复用。
* Fragment可以响应自己的输入输出事件有自己的生命周期。但是收到Activity的控制。
>Fragment主要是为了简化大屏手机的UI的设计。
* **创建Fragment**
onCreate()系统创建Fragment回调的方法
onCreateView()当Fragment绘制界面时回调这个方法
onPause()用户离开Fragment后回调的方法
## &gt;Fragment与Activity通信
----
* 在布局文件中使用<Fragment.../>元素添加Fragment
```
<Fragment
android:name="org.BookListFragment" //指定Fragment的实现类
Android:id="@+id/book_list"
Android:layout_height="match_parent"
android:layout_weight="1"/>
```
* 在java代码中通过FragmentManager对象实现。getFragmentManager()返回FragmentManagerbeginTransaction()启动返回FragmentTransaction对象。
## &gt;Fragment管理与Fragment事物
----
* FragmentManager可以完成的功能
* FragmentManager.findFragmentById()/...ByTag()获取指定的Fragment
* popBackStack()将Fragment从后台栈中弹出
* 调用addOnBackStackChangeListener()注册监听器
* add()
* remove()
* commit()
* replace()
## &gt;Fragment 的生命周期
----
* 四种不同的状态
* 运行状态,fragment位于前台获取焦点
* 暂停状态,activity位于前台Fragment可见
* 停止状态Fragment不可见失去焦点
* 销毁状态fragment被删除。
* 生命周期的控制函数。
> 以下的函数都是回调函数,在不同的时间被触发调用
* onAttach()当Fragment被添加到Activity中时
* onCreate()创建Fragment时
* onActivityCreated()当所在Fragment所在的Activity被启动时
* onCreateView()每次创建绘制该Fragment的View组件时
* onStart()启动Fragment时
* onResume()恢复Fragment时
* onPause()暂停Fragment时
* onStop()停止Fragment时
* onDestroyView()销毁Fragment包含的组件时
* onDestroy()销毁Fragment时
* onDetach()将该Fragment从Activity中删除时

View File

@@ -0,0 +1,210 @@
# 第四章Activity与Fragment的应用
----
## &gt;建立配置和使用Activity
----
* activity能够提供许多不同的操作页面它们做成Activity栈当前活动的应用位于栈顶。
* **LauncherActivity&&ArrayAdapter**
每一个列表项对应一个intent用于保存启动不同的activity的相关信息。
intentForPostion提供了位置和不同activity对应的信息将列表项链接到制定的intent。
* **ExpandableListActivity&&ExpandableListAdapter**
设置界面显示过程中,使用了适配器的相关函数,其中复写的函数能够自动调用生成相应的界面。
* getChild()获得子字表的内容
* getChildID()获得子表的id
* getChildrenCount()获得子表的项目数量
* TextView()获得每个子表的textView配置
* getChildView()获得每个子表的textView内容
* getGroup()获得主表
* getGroupCount()获得主表的数量
* getGroupId()获得主表的id
* getGroupView()决定主表的外观
* isChildSelectable()返回被选中的子表像
* hasStableIds()返回id
当在ExpandableListActivity中定义Adapter时这些函数必须都被复写保证能够生成一个新的列表就相当于XML对应的配置属性一样这样才能完整的显示整个表格。
* **PreferenceActivity&&PreferenceFragment**
1. 实现了参数设置界面让Fragment集成了PreferenceFragment
2. 在onCreate中调用addPreferencFromResource()方法,加载制定的界面布局文件。
* **在manifest.xml中配置多个Activity资源**
2. 配置多个Activity
```
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
```
## &gt;启动和关闭Activity
----
* **启动activity的两种方法**
* context.startActivity(intent)
* context.startActivity(intent,int)
* **关闭Activity的两种方法**
* context.finish()
* context.finishActivity(int)
* **代码示例**
```
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
```
## &gt;使用Bundle向指定的activity传递数据
----
* **intent携带额外数据的方法**
* putExtras(Bundle)
* getExtras()
* putExtra()
* getXxxExtra()
* putXXX(String,XXX)
* putSeriaLizable(String,Srializagle)
* getXXX(String)
* getSerializable(String,Serializable)
* **使用bundle和intent机制向指定的activity传递数据的方法**
* 定义方法向介质添加批数据并且将介质传递给目标activity
```
Person p = new Person(name.getText(),toString(),passwd.getText().toString(),gender);
Bundle data = new Bundle();
data.putSerializable("person),p);
Intent intent = new Intent(MainActivity.this,ResultActivity.class);
intent.putExtras(data);
startActivity(intent);
```
* 使用方法,从传递过来的intent中提取数据
```
Intent intent = getIntent();
Person p = (Person) intent.getSerializableExtra("person");
```
## &gt;启动Activity并且获取返回结果
* 当前的Activity启动另一个Activity获取它的结果并且返回到当前的Activity。
* **实现方法**
重写onActivityResult(int requestCode,int resultCode,intent intent)方法相当于一种回调方法当被启动的Activity生命周期结束并且返回结果时该方法将会被触发。
* **实现过程**
1. 用特殊函数启动另外的activity
```
Intent intent = new Intent(MainActivity.this,ResultActivity.class);
intent.putExtras(data);
startActivityForResult(intent,0);
```
2. 当activity结束时触发onActivity函数需要重写它。
3. 在另外的activity中仍旧需要bundle和intent进行配合传递数据
>对类的补充:
### Intent类交互介质
* **Intent类作用**
每个应用程序都有若干个Activity组成每一个Activity都是一个应用程序与用户进行交互的窗口呈现不同的交互界面。因为每一个Acticity的任务不一样所以经常互在各个Activity之间进行跳转在Android中这个动作是靠Intent来完成的。你通过startActivity()方法发送一个Intent给系统系统会根据这个Intent帮助你找到对应的Activity即使这个Activity在其他的应用中也可以用这种方法启动它。
* **Intent的定义**
Intent是Android系统用来抽象描述要执行的一个操作也可以在不同组件之间进行沟通和消息传递。
Intent意图可以是明确的指定组件的名称这样你可以精确的启动某个系统组件比如启动一个Activity。它也可以是模糊的没有指定组件名称只要是能够匹配到这个Intent的应用都可以接收到比如发送一个拍照Intent所有的拍照应用都会响应。
* **Intent有以下几个属性**
动作(Action),数据(Data),分类(Category),类型(Type),组件(Compent)以及扩展信(Extra)。其中最常用的是Action属性和Data属性。
###Bundle类(批数据,是一个键值对)
* **Bundle类的作用**
Bundle主要用于传递数据它保存的数据是以key-value(键值对)的形式存在的。我们经常使用Bundle在Activity之间传递数据传递的数据可以是boolean、byte、int、long、float、double、string等基本类型或它们对应的数组也可以是对象或对象数组。当Bundle传递的是对象或对象数组时必须实现Serializable 或Parcelable接口。下面分别介绍Activity之间如何传递基本类型、传递对象。
* **Bundle的定义和使用**
* 新建一个bundle类
view plain copy
Bundle mBundle = new Bundle();
* bundle类中加入数据key -value的形式另一个activity里面取数据的时候就要用到key找出对应的value
view plain copy
mBundle.putString("Data", "data from TestBundle");
* 新建一个intent对象并将该bundle加入这个intent对象
view plain copy
Intent intent = new Intent();
intent.setClass(TestBundle.this, Target.class);
intent.putExtras(mBundle);
* Bundle提供了各种常用类型的putxxx()/getxxx()方法,用于读写基本类型的数据。
## Context类的主体上下文
----
* **Context类的定义**
Interface to global information about an application environment. This is an abstract class whose implementationis provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc
* **Context使用场景**
1. 它描述的是一个应用程序环境的信息,即上下文。
2. 该类是一个抽象(abstract class)类Android提供了该抽象类的具体实现类(后面我们会讲到是ContextIml类)。
3. 通过它我们可以获取应用程序的资源和类也包括一些应用级别操作例如启动一个Activity发送广播接受Intent信息
* **Context类图集成关系**
![context类图继承关系](http://hi.csdn.net/attachment/201203/1/0_1330607569Vj4c.gif)
* **Context相关的方法**
* getSystemService(String)获得系统级服务
* startActivity(Intent)启动一个Activity
* startService(Intent)启动一个service
* getSharedPreferences(String, int)
* **Context什自己的理解**
Context类相当于一个上下文环境能够很好的统筹一个Activity、service或者app的资源和调度方式他是负责指挥这些资源的类的接口他能启动关闭一个app等。
### Serializable类
----
> 序列化的内容补充
> 当两个进程在进行远程通信时彼此可以发送各种类型的数据。无论是何种类型的数据都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列才能在网络上传送接收方则需要把字节序列再恢复为Java对象。 把Java对象转换为字节序列的过程称为对象的序列化把字节序列恢复为Java对象的过程称为对象的反序列化。
* **Serializable接口的定义**
为了保存在内存中的各种对象的状态也就是实例变量不是方法并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保存object states但是Java给你提供一种应该比你自己好的保存对象状态的机制那就是序列化。
* **使用情况**
* 当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
* 当你想用套接字在网络上传送对象的时候;
* 当你想通过RMI传输对象的时候
* **Parcelable和Serializable的区别**
内存间数据传输时推荐使用Parcelable,activity间传输数据使用Parcelable是Android特有功能效率比实现Serializable接口高效可用于Intent数据传递也可以用于进程间通信IPC
保存到本地或者网络传输时推荐使用Serializable
### Parcelable类
* **Parcelable类的作用**
想要在两个activity之间传递对象那么这个对象必须序列化Android中序列化一个对象有两种方式一种是实现Serializable接口这个非常简单只需要声明一下就可以了不痛不痒。但是android中还有一种特有的序列化方法那就是实现Parcelable接口使用这种方式来序列化的效率要高于实现Serializable接口。不过Serializable接口实在是太方便了因此在某些情况下实现这个接口还是非常不错的选择。
* **Parcelable类的使用情况**
* 永久性保存对象,保存对象的字节序列到本地文件中;
* 通过序列化对象在网络中传递对象;
* 通过序列化在进程间传递对象。
* **Parcelable接口定义**
```
public interface Parcelable
{
//内容描述接口,基本不用管
public int describeContents();
//写入接口函数,打包
public void writeToParcel(Parcel dest, int flags);
//读取接口目的是要从Parcel中构造一个实现了Parcelable的类的实例处理。因为实现类在这里还是不可知的所以需要用到模板的方式继承类名通过模板参数传入
//为了能够实现模板参数的传入这里定义Creator嵌入接口,内含两个接口函数分别返回单个和多个继承类实例
public interface Creator<T>
{
public T createFromParcel(Parcel source);
public T[] newArray(int size);
}
}
```
* **实现序列化的步骤**
1. implements Parcelable
2. 重写writeToParcel方法将你的对象序列化为一个Parcel对象将类的数据写入外部提供的Parcel中打包需要传递的数据到Parcel容器保存以便从 Parcel容器获取数据
3. 重写describeContents方法内容接口描述默认返回0就可以
4. 实例化静态内部对象CREATOR实现接口Parcelable.Creator

View File

@@ -0,0 +1,119 @@
# android第五章Intent和IntentFilter的进行通信
-----
## &gt;intent对象的描述
----
* intent的理解
intent用来表示自己的意图需要启动哪个Activity。两个Activity可以吧需要交换的数据封装成Bundle对象然后使用Intent来携带Bundle对象这样就实现了两个Activity对象之间的数据交换
* 组件的启动方法
1. Activity
* startActivity(intent)
* startActivity(intent,int)
2. Service
* StartService(Intent)
* bindService(inten,seviceConnection,int)
3. BroadcastReceiver
* sendBroadcast(intent)
* sendBroadcast(intetn,String)
* sendOrderedBroadcast(intent,String,BraodcastReceiver,Handler,int,String,Bundle)
* sendOrderedBroadcast(intet,String)
* sendStickyBroadcast(intent)
* sendStickyOrderedBroadcast(intent,resultReceiver,scheduler,initialCode,String,Bundle)
* 包含的属性
Component,Action,Category,Data,Type,Extra,Flag
## &gt;intent的属性及intent-filter配置
----
* Component属性
* intent设定component属性的方法
setClass(Context packageContext,Class<?> cls)
setClassName(Context packageContext,String className)
setClassName(String packageName,String className)
分别通过应用环境接口Context类component类和字符串的方式实现了指定启动对象的方法
* 启动Activity的中组件的具体方法
> MainActivity.this表示自身在内部使用外部类的时候这样表示。
```
ComponentName comp = new ComponentName(MainActivity.this,secondActivity.class
Intent intent = new Intent();
intent.setComponent(comp)
startActivity(intent)
```
* Action属性的配置
是一个字符串制定Intent要去完成的一个抽象的动作。Action的值可能是intent.ACTION_VIEW具体查看什么取决于<intent-filter/>
可以通过setAction方法这只Action属性
```
Intent intetn = new Intent();
intetn.setAction(MainActivity.CRAZYIT_ACTION);
startActivity(intent)
```
* Category属性的配置
可以通过add
是一个字符串为Action增加额外的附加信息。可以指定多个Category要求
* intent-filter的配置这是被启动的Activity的配置文件配置的事目标activity的intent属性这个是activity的唯一标识。
> 开始有点理解这些东西了可能就是一个用来交互的实体类对于每一个对象的唯一身份标识只需要创建一个这个实体就能通过相同的方式启动类并且通过Bundle传递相应的参数。
```
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
```
* 指定Action、Category调用系统的Activity
1. ACTION_MAIN
2. ACTION_VIEW
3. ACTON_ATTACH_DATA
4. ACTION_ATTACH_DATA
5. ACTION_EDIT。。。。。。。
6. CATAGORY_DEFAULT
7. CATEGORY_BROWSABLE
8. CATEGORY_TAB
* 在intent-filter中设置用户访问手机的权限
<user-permission android:name"android.permission.READ_CONTACTS"/>设置按钮,系统返回桌面
* Datatype属性的配置
向action提供操作的数据data属性可以接受一个URI对象scheme/hostport/path
content://com.android.contacts/contacts/1
tel:123
Type属性用来指定Data所对应的URI的MIME类型。
> Toast.makeText(this.intent.toString(),Toast.LENGTH_LONG).show()相当于弹窗程序,可以用来检测数据的值。
--在androidManifest.xml中实现data和type属性的配置方法
<data andriod:mimeType=""
android:scheme=""
android:host=""
android:port=""
android:path=""
android:pathPrefix=""
android:pathPattern=""/>
其中data元素匹配启动的方式是不完全匹配只要已经显示定义的值相同就能启动相应的activity。其中如果帮同事这只了Action和Data属性则能够同时通过两者启动Activity。
当启动了多个Activity时系统会显示打开这个请求的应用选择界面。也就是说平时会看到的选择某个应用打开这个文档就是通过这种方式实现的通过指定Data和Type属性来定位不同的应用。
> 通过Action和data属性的组合应用可以达到和系统交互信息的功能就是简单的调用系统固有的组件启动系统中本身存在的Activity
* Extra属性
用来在多个Action之间进行数据交互Extra是一个Bundle对象类似于C++中的map类
* Flag属性
为intent添加一些额外的控制标志通过addFlags()方法实现。
* FLAG_ACTIVITY_BROUGHT_TO_FRONT不会被杀死的Activity启动。
* FLAG_ACTIVITY_CLEAR_TOP弑父线程
* FLAG_ACTIVITY_NEW_TASK创建一个新的Ativity
* FLAG_ACTIVITY_NO_ANIMATION不使用过度动画
* FLAG_ACTIVITY_NO_HISTORY将被启动线程弹出工作栈
* FLAG_ACTIVITY_REORDER_TO_FRONT带到前台
* FLAG_ACTIVITY_SINGLE_TOP只会启动一个这样的activity

View File

@@ -0,0 +1,185 @@
# android应用资源(一)
-----
## &gt;应用资源概述
----
* 访问方式分类
1. 无法通过R资源清单类访问的原生资源保存在assets目录下
2. 可通过R资源清单访问的资源保存在res目录下
* 源代码按照物理存储形式分类
1. 界面布局文件
2. java资源文件
3. 资源文件android应用资源
* 资源的类型和存储方式
1. /res/animator/ 定义属性动画
2. /res/anim/ 定义补间动画
3. /res/color/ 定义颜色列表
4. /res/draWble/ 存放各种位图
5. /res/layout/ 存放布局界面
6. /res/menu/ 存放菜单资源
7. /res/raw/ 存放原生资源(音乐视频)
8. /res/value/ 存放简单值,字符串值、整型值、颜色值、数组等
9. /res/xml/ 原生的XML内容
* 使用资源
1. 在java文件中访问Pacage_name.R.resource_type.resource_name;
> 在这里使用的是资源清单,而不是实际资源,所储存到的东西不过是指向资源的一个整型数组。
2. getResources().getText(R.String.main_title)通过引用返回实际资源,用来建立资源副本
Drawable logo = res.getDrawavle(R.drawable.logo);
3. 在XML文件中访问@pacage_name:resource_type/resource_name
## &gt;字符串、颜色、尺寸资源
* 颜色值的定义#ARGB都是十六进制书
`<String name="CSD">这是一个字符串</String>`
`<color name="c1">#FOO</color>`
`<dimen name="spacing">8dp</dimen>`
`<bool name="is_male"> true </bool>`
* 字符串颜色尺寸资源的使用
```
<TextView
android:text="@string/app_name"
android:textsize="@dimen/title_font"
/>
<GridView
android:horizontalSpacing=dimen/spacing
/GridView>
```
* 在java代码中访问如下
```
R.color.c1
R.string.c1
R.dimen.cell_width
R.bool.bool_name
```
## &gt;数组资源
----
* 定义普通数组
```
<array name="plain_arr">
<item>@color/c1</item>
<item>@color/c2</itme>
</array>
```
* 定义字符串数组
```
<string-array name="plain_arr">
<item>@string/c1</item>
<item>@string/c2</itme>
</string-array>
```
* 定义整型数组
## &gt;使用Drawable资源
----
* 使用方式
```
@package_name:drawable/file_name
package_name.R.drawable.file_name
```
* StateListDrawable资源
能够根据目标组件的状态切换不同的分辨率图片。
支持的属性
android:stata_active
android:state_checkable
android:state_cheked
android:state_enable
android:state_first
android:state_focused
android:state_last... ...
* 具体使用说明
1. 在res\drawnable\my_image.xml中建立如下内容。本质上是在原来直接显示图片的基础上进行一次封装是的显示的图片具有动态变化的效果。
```
<sector xmlns:android="http:\\">
<item android:state_focused="true"
android:color="#f44"/>
<item android:state_focused="false"
android:color="#ccf"/>
```
## &gt;使用LayerDrawable资源
----
* 能够支持的属性
anroid:drawble制定图片对象
android:id指定对象的id
android:buttonm tom left button指定显示的位置。
* 使用的语法格式
<layer-list xmlns:android="http://"
<item android:id="@android:id/background"
android:drawable="@drawble/grow"/>
</layer-list>
* 内涵解释:
与StateListDrawable相似包含以个Drawable数组在不同的情况下调用不同的图片。
## &gt;使用ShapeDrawable资源
----
* 作用:
用来定义一个基本的图形(矩形、线条、圆形)
* 使用:(下一级标签)
<corners />定义了四个角的弧度
<gradient /> 定义了渐变色填充
<padding />定义了几何形状内边距
<size /> 定义几何形状的大小
<solid /> 定义使用单种颜色填充
<stroke /> 定义为集合形状绘制边框
## &gt;ClipDrawable资源
----
* 作用
从其他位图上截取一个图片片段
* 使用:(这个标签的属性)
android:drawable指定截取的资源
android:clipOrientation指定截取的方向
android:gravity指定截取时的对其方式
## &gt;AnimationDrable资源
----
* 作用:
代表一个动画,相当于逐帧动画,也可以通过平移、变换计算出来的补间动画。
<alpha />:设置透明度
<scale />:图片进行缩放变换
<translate />:图片进行位移变换
<rotate />:图片进行旋转
android:interpolator属性指定变化速度linear_interpolator/accelerate_interploator/decelerate_interpolator:匀速变化/加速变化/减速变化。
* 使用方法:
* 在XML文件中访问
@package_name:anim/file_name
* 在java代码中访问
package.R.anim.file_name
## &gt;属性动画资源
----
* 子类
AnimatorSet、ValueAnimator、ObjectAnimator、TimeAnimator
* 定义属性动画的根元素
* ```<set> </set>```
* ```<objectAnimator> </objectAnimator>```
* ```<animator> </animator>```

View File

@@ -0,0 +1,154 @@
# android应用资源(二)
-----
## &gt;使用原始XML资源
----
* 文件路径:
在/res/xml/路径下创建xml内容。
* 访问方式:
* java中package_name.R.xml.file_name
* @package_name:xml/file_name
* 获得实际的XML文件的方法
* XmlResourceParser getXml(int id),使用XMLPullParser来解析该XML文档该方法返回一个解析器对象XMLResourceParser是XmlPullParser的子类
* InputStream openRawResource(int id)获取xml文档对应的输入流。
* 使用XML文件
XmlResourceParser xrp = getResources().getXml(R.xml.books)
xrp.getName()获取标签名
xrp.getAttributedValue(null,"price");根据属性名获取属性值
xrp.getAttributeVale(1);根据属性的索引来获取属性的值
xrp.nextText()获取文本内容
xrp.next()下一个事件
## &gt;使用布局文件
----
> 参照第二章内容
## &gt;使用菜单资源
----
> 参照第二章内容
## &gt;样式和主题
----
> 感觉样式和主题就有点像html中css的作用负责通过xml定义一系列完整的格式而普通的java代码就像网页前端中js脚本负责完成前端的简单页面逻辑普通的xml代码就像html代码负责整体的布局。
* 样式的含义相当于多个格式的集合其他UI组件通过style属性来指定样式。
* 样式的定义:
* name:指定样式的名称
* parent:指定继承的父样式,获得父样式中的所有格式,同时可以覆盖父样式
```
<resources>
<style name="style1">
<item name="android:textSize">20sp</item>
<item name="android:textColor">#00d</item>
</style>
</resources>
```
* 样式的使用style = "@package_name:style/file_name"
* 主题资源不能作用于单个View组件主体应该对整个应用中所有的Activity起作用或对指定的Activity起作用。主要是定义窗口外观的格式。
* 主题资源的定义方法
```
<style name="CrazyTheme">
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowFrame">@drawable/star</item>
</style>
```
* 主题资源的使用方法:
* java:setTheme(R.style.CrazyTheme);指定单一的Activity应用主题
* manifest.xml<application andorid:theme="@style/CrazyitTheme"></application>;对整个工程使用某个主题。
* xml在单个Activity中使用某个主题<activity android:theme="@style/CrazyTheme"></activity>
> android内置了大量的主题资源
## &gt;属性资源
----
* 属性资源的定义:
* attr子元素定义了一个属性
* declare-styleable子元素定义了一个styleable对象包含了一组attr属性值。
* 属性资源的使用:
```
TypedArray typedArray=content.obtaintStyledattributes(attrs,R.styleable.alphaImageView);
int duration= typedArray.getInt(R.styleable.AlphaImageView_duration,0)
alphaDelta = 255 * SPEED / duration;
```
## &gt;使用原始资源
----
* 存放位置:/res/raw/或者/assets/目录下前者会在R资源清单中生成一个索引项。后者是更彻底的原始资源android需要通过AssetManager来管理该目录下的原始资源。
* R清单中的访问方式@package_name:raw/file_name;或者package_name.R.raw.file_name;
* asset中访问方式
* InputStream open(String fileName):根据文件名来获取原始资源对应的输入流
* AssetFileDescriptor openFd(String fileName):根据文件名来获取原始资源对应的AssetFileDescriptor。AssetFileDescriptor代表了一项原始资源的描述应用程序可以通过AssetFileDescriptor来获取原始资源。
## &gt;国际化和资源自适应
----
* java实现国际化的方法
将标签和提示等信息放在资源文件中资源文件是键值对对每个资源文件中的key是不变的但value随着不同的国家和语言改变。
* java程序国际化的实现方法
* java.util.ResourceBundle:加载一个国家的语言包
* java.util.Locale:用于封装一个特定的国家区域、语言环境。
* java.text.MessageFormat:用于格式化带占位符的字符串。
* baseName_language_country.properties
* baseName_laguage.properties
* baseName.properties
* java支持的国家和语言
* 程序国际化的具体实现方法:
* 在不同国家的properties文件中定义大量的键值对并将两个字节的值进行转换(native2ascii)。
* 获得当前系统的国家语言环境Locale = Locale.getDefault();
* 加载制定国家地区的properties文件,将得到的键值对放在bundle中
ResourceBundle bundle = ResourceBundle.getBundle("mess",myLocale);
* 取出键值对中的值
System.out.println(bundle.getString("hello"));
>其他程序国际化的方法也一样,能够通过(资源-国家-r语言的方式来定义不同的国家。
## &gt;自适应不同屏幕的资源
----
* 屏幕资源:屏幕尺寸,屏幕分辨率、屏幕方向
> 对dp和dpi的理解
> dp出现的原因是android手机屏幕分辨率各不相同同如果用px像素点来描述会导致在不同的手机屏幕上效果差异较大。dp的目的是为了封装屏幕的分辨率。对于任何屏幕他的dp都是480dp*320dp如果分辨率更高那么1dp就等于更多的px如果分辨率更低1dp就等于更少的px。其中dp和平乡的换算公式被称为dpi就是单位dp中含有像素的个数或者说单位inch中含有像素点的个数。
----
> 事实上dp的工作机制跟上述内容不同但是为什么采取一种错误的理解方式因为他们的机制一样但是结果不一样。
----
> 那就应该用学习html中的方法机制理解起来可能比较简单重要的是对标签的记忆组合与对审美的要求。而js和android中的java代码则对逻辑要求比较严谨。

View File

@@ -0,0 +1,79 @@
# 第七章图形与图像处理(动态处理)
----
## 逐帧动画
------
* AnimationDrawable与逐帧动画。在<animation-list/>元素中定义<item/>子元素,表示动画的全部帧,并制定持续时间即可。
```
<animation-list xmlns:android=""
android:onshot=true/false>
<item android:drawable="@package_name:drawable/resource_name"
android:duration="integer"/>
</animation-list>
```
## 补间动画
----
* android使用Animation代表抽象的动画类
* AlphaAnimation:透明度改变的动画,指定开始透明度、结束透明度、动画持续时间
* ScaleAnimation:大小缩放的动画,指定缩放中心、开始缩放比、结束缩放比、动画持续时间
* TranslateAnimation:位移变化的动画,指定开始位置、结束位置、动画持续时间
* RotateAnimation:旋转动画,旋转轴心、开始旋转角度、结束旋转角度
* 通过interpolator指定动画运行期间动态补入多少帧在哪些时刻补入。能够指定动画的变化速度。
* interpolator的实现类
* LinearInterpolator:均匀速度改变
* AccelerateInterpolator:加速
* AccelerateDecelerateinterpolator:中间加速
* CycleInterpolator:循环播放n次变化速度正玄曲线
* DecelerateInterpolator:减速
* 自定义补间动画
* 继承Animation重写抽象基类的interpolatedTime时间进行比方法和Transformation补间动画变形程度。
* Transformation代表了对图片或者视图的变形程度封装了一个Matrix对象用来对图形进行位移、倾斜、旋转等变换。封装了一个Camera对象进行三维空间变换。getMatrix():将Camera所有变换应用到matrix上
* getMatrix():Camera对应变换应用到matrix上
* rotateX:X轴旋转
* rotateY():Y轴旋转
* rotateZ():Z轴旋转
* translate():目标组件在三维空间内变换
* applyToCanvas():应用到场景当中
## 属性动画
-----
* 属性变化可以定义任意性质的变化。可以针对任何对象执行的动画,需要制定动画持续时间、动画的插值方式、动画的重复次数、重复行为、动画集、帧刷新率
* 属性动画的API
* Animator:提供了创建属性动画的基类。
* ValueAnimator:属性动画主要的时间引擎,负责计算各个帧的属性值,定义了属性动画的绝大部分核心功能。
* ObjectAnimator:对指定对象的属性执行动画是ValueAnimator的子类
* AnimatorSet:组合多个Animator并制定多个Animator的播放次序。
* IntEvaluator:计算int属性值的计算器。
* FloatEvaluator:计算float类型的计算器
* ArgbEvaluator:计算十六进制颜色值的计算器
* TypeEvaluator:计算器接口。自定义计算器。
* ValueAnimator创建属性动画的步骤
1. 调用ofInt() ofFloat() ofObject()静态方法创建ValueAnimator实例
2. 调用setXxx() 方法设置动画持续时间,差值方式、重复次数
3. 调用start()方法启动动画
4. 为ValueAnimator注册AnimatorUpdateListener监听器监听ValueAnimator计算出来的值并将这些值应用到制定对象上。通过getAnimatorValue()方法来计算值,并应用到任何对象上。
* ObjectAnimator创建属性动画的步骤
* 继承了ValueAnimator已经绑定了指定的对象直接将ValueAnimator计算的值应用到制定对象的指定属性上。
* 必须为绑定的制定对象提供特定的setter方法才行。如果没有开始值必须提供getter方法提供开始值。
* 如果对象是View需要调用onAnimationUpdate()中调用View.invalidate()方法来刷新屏幕显示。
## 使用SurfaceView实现动画
----
* SurfaceView与SurfaceHolder相互关联使用后者提供了方法
* lockCanvas()锁定surfaceView对象或者对指定区域更新。

View File

@@ -0,0 +1,113 @@
# 第七章图形与图像处理(静态处理)
> Bitmap是有像素点构成的点阵图。
------
## 使用简单的图片
----
* 通过Drawable对象进行访问。
R.drawable.file_name
@drawable/file_name
* 通过BitmapDrawable对Bitmap对象进行封装以下皆为静态方法来自BitmapFactory。
* BitmapDrawagle drawable - new BitmapDrawable(bitmap);通过Bitmap对象的到另外的图像
* createBitmap(Bitmap source,int x,int y,int width, int height):从源位图source的制定位置开始截取一个图像。
* createScaledBitmap(Bitmap src,int dstWidth,int dstHeight,boolean filter):对原来的位图进行缩放
* createBitmap(int width,int height,Bitmap.Config config):创建一个宽width、height的新位图
* createBitmap(Bitmap source,int x,int y,int width,int height,Matris m,boolean filter);截取一段图像
* decodeByteArray(byte[],int offset, int length);从指定字节数组的offset位置开始将长度length的字节解析成Bitmap对象。
* decodeFile(String pathName):从pathName指定文件中解析、创建Bitmap对象
* 用来判断是否被回收: isRecycled()
用来强制回收recycle()
* 使用静态方法导入一张图片:
* AssetManager assets=getAssets();
* InputStream assetsFile = assets.open(images[currentImg++]);
* BitmapDrawable bitmapDrawable=(BitmapDrawable) image.getDrawable();
* image.setImageBitmap(BitmapFactory.decodeStream(assetFile));
## &gt;绘图
----
* 绘图基础
* 集成View组件重写onDraw()回调方法。
*使用Canvas画布进行画图
* drawArc()
* drawBitmap()
* drawCircle()
* drawLine()
* drawLines(),drawOvl()
* drawPath(),drawPoint()
* drawPoints(),drawRect()
* drawRoundRect()
* drawText()
* drawTextOnPath()
* clipRect()
* clipRegion();
* Canvas坐标变换rotate()旋转,scale()缩放,skew()倾斜,translate()移动;
* 使用Paint进行绘图
* setARGB()设置颜色。
* setAlpha()设置透明度
* setColor()设置颜色
* setPathEffect()设置路径
* setShader()设置画笔的填充效果
* setShadowLayer()设置阴影
* setStrokeWidth()设置笔触宽度
* setStrokeJoin()设置笔转风格
* setStyle()设置paint的填充风格
* setTextAlign()设置文字对齐方式
* setTextSize()设置文本的文字大小。
* 使用Path类
* 预先将N个点连成一条路径然后在路径上绘制
* 子类ComposePathEffect/CornerPathEffect/DashPathEffect/DiscretePathEffect/SumPathEffect
* 绘图应用-绘制有用游戏
重复调用onDraw()方法每次在View组件上绘制不同的东西形成逐帧动画。
* 双缓冲画图板
* 弹球游戏
## &gt;图形特效处理
----
* 使用Matrix控制变换步骤
1. 获取Matrix对象
2. 调用Matrix的方法进行变换矩阵方法
3. 将程序Matrix所做的变换应用到指定图形或组件。
* Matrix提供的方法
* setTranslage
* setSkew()
* setTotate()
* setScale()
* Matrix 应用举例
* 键盘操作图片移动
* 移动游戏背景
* 使用drawBitmapMesh扭曲图像
* bitmap:扭曲的源位图
* meshWidth/meshHeight划分格子数
* verts扭曲后个顶点的位置
* vertOffset:控制verts数组中扭曲的开始。
* 通过drawBitmapMesh()方法对源位图扭曲绘制。
* drawBitmapMesh 应用举例
* 可揉的图片
## &gt;使用Shader填充图形
----
* 使用Shader对象指定渲染效果来填充图像。子类
* BitmapShader位图平铺
* LinerGradient线性渐变
* RadialGradient圆形渐变
* SweepGradient角度渐变
* ComposeShader组合渲染效果

View File

@@ -0,0 +1,341 @@
# 第8章Android数据存储于IO接口
-----
> Android 内置了sqlife数据库
## 使用sharePreferences
----
* 使用方法SharedPreferences负责读取数据SharedPreferences.Editor负责写入数据。
* contains()是否包含指定key的数据
* getAll()获取sharedPreferences数据里全部的keyValue对
* getXX()得到指定键的值
* clear()清空用户配置
* putXxx()存入键值对
* remove()删除键值对
* commit()提交修改
* 只能通过Context.getSharedPreferences(Stringint)方式来获取Preferences的一个实例。
## File存储
----
* FileInputStream openFileInput(String name)打开应用程序数据文件夹下的那么文件对应的输入流
* FileOutputStream openFileOutput(String name , int mode)打开应用程序数据文件夹下的name文件对应的输出流。模式分别有MODE_PRIVATE(只能被当前程序读写MODE_APPEND(追加方式,应用程序读写)MODE_WORLD_READABLE(被其他程序读取)MODE_WORLD+WRITEABLE(由其他程序读写)
* 相关方法
* getDir()创建name对应的子目录
* getFilesDir()获取应用程序的数据文件夹的绝对路径
* fileList()返回应用程序的数据文件夹下的全部文件
* deleteFile()删除数据文件夹下的制定文件
* 读取SD卡上的文件
* Environment.getExternalStorageState()判断是否插入了SD卡
* Environment.getExternalStorageDirectory()获取外部存储器
* FileInputStream、FileOutputStream、FileReader、FileWriter读写sd卡内容
* 权限配置创建删除文件的权限和向sd卡中写入数据的权限
```
<user-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<USER-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
```
## SQLife数据库
----
* sqlife数据的格式
一般数据采用的固定的静态数据类型而SQLite采用的是动态数据类型会根据存入值自动判断。SQLite具有以下五种常用的数据类型
NULL: 这个值为空值
VARCHAR(n):长度不固定且其最大长度为 n 的字串n不能超过 4000。
CHAR(n)长度固定为n的字串n不能超过 254。
INTEGER: 值被标识为整数,依据值的大小可以依次被存储为1,2,3,4,5,6,7,8.
REAL: 所有值都是浮动的数值,被存储为8字节的IEEE浮动标记序号.
TEXT: 值为文本字符串,使用数据库编码存储(TUTF-8, UTF-16BE or UTF-16-LE).
BLOB: 值是BLOB数据块以输入的数据格式进行存储。如何输入就如何存储,不改 变格式。
DATA :包含了 年份、月份、日期。
TIME 包含了 小时、分钟、秒。
* SQLife提供的数据库访问方式
| 方法名称 | 方法表示含义 |
| -------- |:------------:|
| openOrCreateDatabase(String path,SQLiteDatabase.CursorFactory factory) | 打开或创建数据库 |
| insert(String table,String nullColumnHack,ContentValues values) | 插入一条记录 |
| delete(String table,String whereClause,String[] whereArgs) | 删除一条记录 |
| query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy) | 查询一条记录 |
| update(String table,ContentValues values,String whereClause,String[] whereArgs) | 修改记录 |
| execSQL(String sql) | 执行一条SQL语句 |
| close() | 关闭数据库 |
Google公司命名这些方法的名称都是非常形象的。例如openOrCreateDatabase,我们从字面英文含义就能看出这是个打开或创建数据库的方法。
* SQLife进行数据库操作的具体步骤
1. 获取SQLife对象它代表了与数据库的链接
2. 调用SQLife的方法来执行SQL语句
3. 操作SQL语句的执行结果用SimpleCursorAdaptor封装Cursor
4. 关闭SQLifeDatabase回收资源。
* SQLite3工具
* 只支持五中基本数据类型。null,integer,real,text,blob.
* 使用slite3工具执行相应的命令能够通过命令行管理数据库
* 弱类型的数据库,能够将任何数据类型保存到任何数据类型当中,在创建数据库的时候不必声明具体的数据类型。(主键除外)例如:
```
create table mytest{
id integer primary key,
name ,
gender,
pass ,
}
```
## SQLife具体的操作方式说明
1. 打开或者创建数据库
在Android 中使用SQLiteDatabase的静态方法openOrCreateDatabase(String path,SQLiteDatabae.CursorFactory factory)打开或者创建一个数据库。它会自动去检测是否存在这个数据库如果存在则打开不存在则创建一个数据库创建成功则返回一个SQLiteDatabase对象否则抛出异常FileNotFoundException。
下面是创建名为“stu.db”数据库的代码
openOrCreateDatabase(String path,SQLiteDatabae.CursorFactory factory)
参数1 数据库创建的路径
参数2 一般设置为null就可以了
[sql] view plain copy print?在CODE上查看代码片派生到我的代码片
db=SQLiteDatabase.openOrCreateDatabase("/data/data/com.lingdududu.db/databases/stu.db",null);
2. 创建表
创建一张表的步骤很简单:
编写创建表的SQL语句
调用SQLiteDatabase的execSQL()方法来执行SQL语句
下面的代码创建了一张用户表属性列为id主键并且自动增加、sname学生姓名、snumber学号
[sql] view plain copy print?在CODE上查看代码片派生到我的代码片
private void createTable(SQLiteDatabase db){
//创建表SQL语句
String stu_table="create table usertable(_id integer primary key autoincrement,sname text,snumber text)";
//执行SQL语句
db.execSQL(stu_table);
}
3. 插入数据
插入数据有两种方法:
①SQLiteDatabase的insert(String table,String nullColumnHack,ContentValues values)方法,
参数1 表名称,
参数2 空列的默认值
参数3 ContentValues类型的一个封装了列名称和列值的Map
②编写插入数据的SQL语句直接调用SQLiteDatabase的execSQL()方法来执行
第一种方法的代码:
[sql] view plain copy print?在CODE上查看代码片派生到我的代码片
private void insert(SQLiteDatabase db){
//实例化常量值
ContentValues cValue = new ContentValues();
//添加用户名
cValue.put("sname","xiaoming");
//添加密码
cValue.put("snumber","01005");
//调用insert()方法插入数据
db.insert("stu_table",null,cValue);
}
第二种方法的代码:
[sql] view plain copy print?在CODE上查看代码片派生到我的代码片
private void insert(SQLiteDatabase db){
//插入数据SQL语句
String stu_sql="insert into stu_table(sname,snumber) values('xiaoming','01005')";
//执行SQL语句
db.execSQL(sql);
}
4. 删除数据
删除数据也有两种方法:
①调用SQLiteDatabase的delete(String table,String whereClause,String[] whereArgs)方法
参数1 表名称
参数2 删除条件
参数3 删除条件值数组
②编写删除SQL语句调用SQLiteDatabase的execSQL()方法来执行删除。
第一种方法的代码:
[sql] view plain copy print?在CODE上查看代码片派生到我的代码片
private void delete(SQLiteDatabase db) {
//删除条件
String whereClause = "id=?";
//删除条件参数
String[] whereArgs = {String.valueOf(2)};
//执行删除
db.delete("stu_table",whereClause,whereArgs);
}
第二种方法的代码:
[sql] view plain copy print?在CODE上查看代码片派生到我的代码片
private void delete(SQLiteDatabase db) {
//删除SQL语句
String sql = "delete from stu_table where _id = 6";
//执行SQL语句
db.execSQL(sql);
}
5. 修改数据
修改数据有两种方法:
①调用SQLiteDatabase的update(String table,ContentValues values,String whereClause, String[] whereArgs)方法
参数1 表名称
参数2 跟行列ContentValues类型的键值对Key-Value
参数3 更新条件where字句
参数4 更新条件数组
②编写更新的SQL语句调用SQLiteDatabase的execSQL执行更新。
第一种方法的代码:
[sql] view plain copy print?在CODE上查看代码片派生到我的代码片
private void update(SQLiteDatabase db) {
//实例化内容值 ContentValues values = new ContentValues();
//在values中添加内容
values.put("snumber","101003");
//修改条件
String whereClause = "id=?";
//修改添加参数
String[] whereArgs={String.valuesOf(1)};
//修改
db.update("usertable",values,whereClause,whereArgs);
}
第二种方法的代码:
[sql] view plain copy print?在CODE上查看代码片派生到我的代码片
private void update(SQLiteDatabase db){
//修改SQL语句
String sql = "update stu_table set snumber = 654321 where id = 1";
//执行SQL
db.execSQL(sql);
}
6. 查询数据
在Android中查询数据是通过Cursor类来实现的当我们使用SQLiteDatabase.query()方法时会得到一个Cursor对象Cursor指向的就是每一条数据。它提供了很多有关查询的方法具体方法如下
public Cursor query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy,String limit);
各个参数的意义说明:
参数table:表名称
参数columns:列名称数组
参数selection:条件字句相当于where
参数selectionArgs:条件字句,参数数组
参数groupBy:分组列
参数having:分组条件
参数orderBy:排序列
参数limit:分页查询限制
参数Cursor:返回值相当于结果集ResultSet
Cursor是一个游标接口提供了遍历查询结果的方法如移动指针方法move()获得列值方法getString()等.
Cursor游标常用方法
方法名称
方法描述
getCount()
获得总的数据项数
isFirst()
判断是否第一条记录
isLast()
判断是否最后一条记录
moveToFirst()
移动到第一条记录
moveToLast()
移动到最后一条记录
move(int offset)
移动到指定记录
moveToNext()
移动到下一条记录
moveToPrevious()
移动到上一条记录
getColumnIndexOrThrow(String columnName)
根据列名称获得列索引
getInt(int columnIndex)
获得指定列索引的int类型值
getString(int columnIndex)
获得指定列缩影的String类型值
下面就是用Cursor来查询数据库中的数据具体代码如下
[sql] view plain copy print?在CODE上查看代码片派生到我的代码片
private void query(SQLiteDatabase db) {
//查询获得游标
Cursor cursor = db.query ("usertable",null,null,null,null,null,null);
//判断游标是否为空
if(cursor.moveToFirst() {
//遍历游标
for(int i=0;i<cursor.getCount();i++){
cursor.move(i);
//获得ID
int id = cursor.getInt(0);
//获得用户名
String username=cursor.getString(1);
//获得密码
String password=cursor.getString(2);
//输出用户信息 System.out.println(id+":"+sname+":"+snumber);
}
}
}
7. 删除指定表
编写插入数据的SQL语句直接调用SQLiteDatabase的execSQL()方法来执行
[java] view plain copy print?在CODE上查看代码片派生到我的代码片
private void drop(SQLiteDatabase db){
//删除表的SQL语句
String sql ="DROP TABLE stu_table";
//执行SQL
db.execSQL(sql);
}
8. 事务处理
beginTransction()开始事务
endTransaction()结束事务
inTrasaction()判断是否处于事务当中。
setTransactionSuccessful()判断事务是提交还是回滚的函数。具体提交回滚是在endTransaction()部分实现。
9. SQLiteOpenHelper
该类是SQLiteDatabase一个辅助类。这个类主要生成一个数据库并对数据库的版本进行管理。当在程序当中调用这个类的方法getWritableDatabase()或者 getReadableDatabase()方法的时候如果当时没有数据那么Android系统就会自动生成一个数据库。 SQLiteOpenHelper 是一个抽象类我们通常需要继承它并且实现里面的3个函数
1. onCreateSQLiteDatabase
在数据库第一次生成的时候会调用这个方法,也就是说,只有在创建数据库的时候才会调用,当然也有一些其它的情况,一般我们在这个方法里边生成数据库表。
2. onUpgradeSQLiteDatabaseintint
当数据库需要升级的时候Android系统会主动的调用这个方法。一般我们在这个方法里边删除数据表并建立新的数据表当然是否还需要做其他的操作完全取决于应用的需求。
3. onOpenSQLiteDatabase
这是当打开数据库时的回调函数,一般在程序中不是很常使用。
4. synchonized SQLiteDatabase getReadableDatabase()
以读写的方式打开数据库对应的SQLliteDatebase对象
5. synchonized SQLiteDatabase getWritableDatabase()
以写的方式打开对应的对象
6. close
关闭所有打开的SQLiteDatabase对象