前言:建议入门Android的小伙伴作为复习的时候用到,因为涉及比较多的细节知识,不利于你们的前期学习,视频地址:15天精讲精练Android核心技术
Android整体架构图:Android系统架构—–Android的系统体系架构 - xiaoluo501395377 - 博客园
手机尺寸的相关概念:手机尺寸相关的概念 +尺寸单位+关于颜色 - D(a/e)mon - 博客园
0.Activity是四大组件中唯一能与用户进行直接交互的应用组件
1.Intent(意图)是Activity,Service以及BroadcastReceiver这三大组件进行通信的信使
2.在Android中,系统用Task Stack (Back Stack)结构来存储管理启动的Activity对象
3.一个应用启动,系统就会为其创建一个对应的Task Stack来存储并管理该应用的Activity对象
4.只有最上面的任务栈的栈顶的Activity才能显示在窗口中
5.回调方法都是在主线程执行的
6.Activity只是控制和管理View, 真正显示和处理事件的是View本身来完成
面试题:在安卓中哪些用到反射?
1.配置文本中配置全类名(Activity,也就解释了为什么我们不需要使用new创建Activity啦)
2.布局文件定义标签(比如TextView)
3.显示意图:Intent(Context content,class c)
1. startService(intent)
第一次调用 : -->构造方法()-->onCreate()-->onStartCommand()
(重要)后面再调用 : -->onStartCommand()
stopService() : -->onDestory()
2. bindService(intent, serviceConnection)
调用 : -->构造方法()-->onCreate()-->onBind()-->onServiceConnected()
unbindService(): (中有当前Activity与Service连接)-->onUnbind()-->onDestroy()
1.Android Studio中如何创建AIDL - 技术丶从积累开始 - 博客园
2.AIDL-小白成长记-入门视频教程-慕课网
如何区别Service与Activity?
区别Service与Thread
广播接收者的生命周期是很短的,一般是10s内,即处理完它的onReceive()方法就死亡
Context
BroadcastReceiver
1.ContentProvider 浅谈 - 推酷
2.ContentProvider从入门到精通 - 简书
UI全称user interface, 意为:用户界面
1.UI由View和ViewGroup组成
2.View类是所有视图(包括ViewGroup)的根基类
3.View在屏幕上占据一片矩形区域, 并会在上面进行内容绘制
4.ViewGroup包含一些View或ViewGroup, 用于控制子View的布局
当用户通过手指触摸UI时, 系统会自动创建对应的Event对象(事件源一般是视图对象,而不是视图类)
Android中提供了多种方式拦截处理不同类型的事件
视图本身就可以处理发生在该视图上的事件
Android提供了很多不同类型的事件监听器接口
View.OnClickListener: onClick()
View.OnLongClickListener: onLongClick()
View.OnTouchListener: onTouch()
View.OnCreateContextMenuListener: onCreateContextMenu()
View.OnFocusChangeListener: onFocusChange()
View.OnKeyListener: onKey()
给视图添加事件监听的方式:view.seton…Listener(listener),其中listener可以为this,匿名内部类以及成员变量
1.子线程不可以直接更新UI(Toast也是其中一种UI),因为子线程缺少Looper.prepare()方法,
2.与进度相关的控件之所以可以在子线程更新UI,是因为这类控件在它源码内置了已经添加了Handler消息机制
3.runOnUiThread可以在主线程或子线程执行,但它参数的匿名内部类Runnable中的run方法一定是在主线程执行的
4.图片imageView中的background背景图片显示的效果=src前景图片+属性fitXY
5.gravity控制是当前视图的内容/子view,layout_gravity控制当前视图自己
获得日历对象
//创建日历对象
Calendar calendar = Calendar.getInstance();
//得到当前的年月日
final int year = calendar.get(Calendar.YEAR);//得到年份
final int monthOfYear = calendar.get(Calendar.MONTH);//月
final int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);//得到日
int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY); //得到小时
int minute = calendar.get(Calendar.MINUTE); //得到分钟
3.相对布局相关属性比较多:
1.MotionEvent : 触屏事件
2.Activity
1.Android事件分发机制完全解析,带你从源码的角度彻底理解(上) - 郭霖的专栏 - 博客频道 - CSDN.NET
2.关于 android 的 view.getLeft(), getRight(), getTop(), getBottom() 的一些疑惑(坑)解答 - 指尖下的幽灵 - 博客园
sp存储简解:android SharedPreferences的用法 - sangxb - 博客园
步骤:
1.读取文件
FileInputStream fis = openFileInput(“logo.png”);
2.保存文件
FileOutputStream fos = openFileOutput(“logo.png”, MODE_PRIVATE)
3.得到files文件夹对象
File filesDir = getFilesDir();
4.操作asserts下的文件
得到AssetManager : context.getAssets();
读取文件: InputStream open(filename);
5.加载图片文件:Bitmap BitmapFactory.decodeFile(String pathName) // .bmp/.png/.jpg
注意:
1.Drawable是可以描绘的图片,不等同与Bitmap,因为Drawable还包括shape等
2.bitmap对应的是bmp,jpg,png格式的图片
事例代码:
1.把assets文件夹的图片存储到包名下的files目录
//1. 得到InputStream-->读取assets下的logo.png
//得到AssetManager
AssetManager manager = getAssets();
//读取文件
InputStream is = manager.open("logo.png");
//2. 得到OutputStream-->/data/data/packageName/files/logo.png
FileOutputStream fos = openFileOutput("logo.png", Context.MODE_PRIVATE);
//3. 边读边写
byte[] buffer = new byte[1024];
int len = -1;
while((len=is.read(buffer))!=-1) {
fos.write(buffer, 0, len);
}
fos.close();
is.close();
//4. 提示
Toast.makeText(this, "保存完成", 0).show();
2.把包名内的files文件夹下log.png显示在ImageView上
//图片的路径 /data/data/packageName/files/logo.png
//1. 得到图片文件的路径
// /data/data/packageName/files
String filesPath = getFilesDir().getAbsolutePath();
String imagePath = filesPath+"/logo.png";
//2. 读取加载图片文件得到bitmap对象
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
//3. 将其设置到imageView中显示
//ImageView iv_if = (ImageView) findViewById(R.id.iv_if);
iv_if.setImageBitmap(bitmap);
public void save(View v) throws IOException {
//1. 判断sd卡状态, 如果是挂载的状态才继续, 否则提示
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
//2. 读取输入的文件名/内容
String fileName = et_of_name.getText().toString();
String content = et_of_content.getText().toString();
//3. 得到指定文件的OutputStream
//1).得到sd卡下的files路径
String filesPath = getExternalFilesDir(null).getAbsolutePath();
//2).组成完整路径
String filePath = filesPath+"/"+fileName;
//3). 创建FileOutputStream
FileOutputStream fos = new FileOutputStream(filePath);
//4. 写数据
fos.write(content.getBytes("utf-8"));
fos.close();
//5. 提示
Toast.makeText(this, "保存完成", 0).show();
} else {
Toast.makeText(this, "sd卡没有挂载", 0).show();
}
}
public void read(View v) throws Exception {
// 1. 判断sd卡状态, 如果是挂载的状态才继续, 否则提示
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
// 2. 读取输入的文件名
String fileName = et_of_name.getText().toString();
// 3. 得到指定文件的InputStream
// 1).得到sd卡下的files路径
String filesPath = getExternalFilesDir(null).getAbsolutePath();
// 2).组成完整路径
String filePath = filesPath + "/" + fileName;
// 3). 创建FileInputStream
FileInputStream fis = new FileInputStream(filePath);
// 4. 读取数据, 成String
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while((len=fis.read(buffer))!=-1) {
baos.write(buffer, 0, len);
}
String content = baos.toString();
// 5. 显示
et_of_content.setText(content);
} else {
Toast.makeText(this, "sd卡没有挂载", 0).show();
}
}
// /storage/sdcard/atguigu/xxx.txt
public void save2(View v) throws IOException {
//1. 判断sd卡状态, 如果是挂载的状态才继续, 否则提示
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
//2. 读取输入的文件名/内容
String fileName = et_of_name.getText().toString();
String content = et_of_content.getText().toString();
//3. 得到指定文件的OutputStream
//1). /storage/sdcard/
String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
//2). /storage/sdcard/atguigu/(创建文件夹)
File file = new File(sdPath+"/atguigu");
if(!file.exists()) {
file.mkdirs();//创建文件夹
}
//3). /storage/sdcard/atguigu/xxx.txt
String filePath = sdPath+"/atguigu/"+fileName;
//4). 创建输出流
FileOutputStream fos = new FileOutputStream(filePath);
//4. 写数据
fos.write(content.getBytes("utf-8"));
fos.close();
//5. 提示
Toast.makeText(this, "保存完成", 0).show();
} else {
Toast.makeText(this, "sd卡没有挂载", 0).show();
}
}
public void read2(View v) throws Exception {
// 1. 判断sd卡状态, 如果是挂载的状态才继续, 否则提示
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
// 2. 读取输入的文件名
String fileName = et_of_name.getText().toString();
// 3. 得到指定文件的InputStream
String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
String filePath = sdPath+"/atguigu/"+fileName;
FileInputStream fis = new FileInputStream(filePath);
// 4. 读取数据, 成String
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while((len=fis.read(buffer))!=-1) {
baos.write(buffer, 0, len);
}
String content = baos.toString();
fis.close();
// 5. 显示
et_of_content.setText(content);
} else {
Toast.makeText(this, "sd卡没有挂载", 0).show();
}
}
选择内部文件与外部文件存储考虑的要素:
1). 存储空间的大小(内部文件小一点)
2). 是否是私有的(内部文件私有而且卸载时候自动删除,外部文件一般对外开放而且应用卸载时候与其无关)
3). 应用卸载是否自动删除
一般包名下的都是会自动删除的,无论是内部还是外部文件:
即: /data/data/packageName/shared_prefs/yyy.xml
/storage/sdcard/Android/data/packageName/files/
adb shell 进入系统根目录
cd data/data/…/databases : 进入包含数据库文件的文件夹下
sqlite3 contacts2.db : 使用sqlite3命令连接指定的数据库文件, 进入连接模式
.help : 查看命令列表
.tables : 查看所有表的列表
执行insert/delete/update/select语句
.exit : 退出数据库连接模式
Ctrl + C : 直接退出sell模式
RequestQueue : 请求队列, 会自动执行队列中的请求
Request: 代表请求的接口
Android Volley完全解析(一),初识Volley的基本用法 - 郭霖的专栏 - 博客频道 - CSDN.NET
携带数据
public int what;
public int arg1;
public int arg2;
public Object obj;
long when; //保存消息需要被处理的时间
Handler target; //处理消息的handler
Runnable callback; //可以用来处理消息的回调对象
Message next; //保存下一个message对象的引用(用来实现链表)
static Message sPool; //消息池(缓存可复用的message对象)
Message obtain() 使用了sPool
sendMessage(Message msg)
sendMessageDelayed(Message msg, long delayMillis)
sendMessageAtTime(Message msg, long uptimeMillis)
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;//发送消息的handler就是处理消息的handler
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
message.callback.run();//如果message有回调监听对象, 让它处理消息
} else {
if (mCallback != null) {
//如果Handler中设置了回调监听器, 就调用它的处理消息的方法
if (mCallback.handleMessage(msg)) {
//如果返回true, 就结束
//如果返回false, 还会调用handleMessage()
return;
}
}
//如果上面都没有处理, 调用此方法处理
handleMessage(msg);
}
}
Handler主要用于做什么工作?
1.线程间通信(子线程间切换到主线程运行)
2.延迟的工作
3.定时循环工作
boolean enqueueMessage(Message msg, long when) {//将消息添加到消息队列中
msg.when = when;
将消息添加到消息队列
唤醒Looper
public static void loop() {
for (;;) {//死循环
Message msg = queue.next(); //从消息队列中取消息, 如果没有得到合适就会进入等待状态
msg.target.dispatchMessage(msg);//Handler分发并处理消息
msg.recycle();//回收消息(清理数据,保存到消息池中)
}
}
注意:publishProgress()方法是在WorkerThread()执行的,一般写在doInBackground方法里面,当这个方法执行完毕之后,onProgressUpdate方法便会自动执行的啦
Android 图片三级缓存之内存缓存(告别软引用(SoftRefrerence)和弱引用(WeakReference)) - fancychendong的专栏 - CSDN博客
1). 图片的三级缓存
一级缓存: 内存缓存, 缓存的是bitmap对象, 用Map<String, Bitmap>结构保存, key是url
二级缓存: 本地(sd卡)缓存, 缓存的是图片文件, /storage/sdcard/Android/data/packageName/files/图片文件名(xxx.jpg)
三级缓存: 远程服务器缓存, 缓存的是图片文件, 远程服务器上的应用中
2). 如何使用三级缓存? -----如何根据图片的url动态显示图片?
String iamgePath = http://192.168.10.165:8080//L05_Web/images/f10.jpg和ImageView对象
1). 根据url从一级缓存中取对应的bitmap对象
如果有, 显示(结束)
如果没有, 进入2)
2). 从二级缓存中查找: 得到文件名并在sd卡的缓存目录下加载对应的图片得到Bitmap对象
如果有: 显示, 缓存到一级缓存中(结束)
如果没有, 进入3)
3). 显示代表提示正在加载的图片, 启动分线程联网请求得到Bitmap对象
如果没有: 显示提示错误的图片(结束)
如果有:
显示
缓存到一级缓存
缓存到二级缓存
2 . 在ListView使用图片三级缓存会存在图片闪动的bug
1). 原因
converView被复用了
2). 解决
a. 每次getView()都将图片的url保存到ImageView上: imageView.setTag(imagePath)
b. 在分线程准备请求服务器加载图片之前, 比较准备加载图片的url与ImageView中保存的最新图片的url是同一个,
如果不是同一个, 当前加载图片的任务不应该再执行
如果相同, 继续执行加载远程图片
c. 在主线程准备显示图片之前, 比较加载到图片的url与ImageView中保存的最新图片的url是同一个
如果不是同一个, 不需要显示此图片
如果相同, 显示图片
三级缓存主要代码:http://pan.baidu.com/s/1bKCNq2 密码: 91py (里面有相关的源码以及配套的服务器,使用前麻烦看看说明哈)
0.Android高效加载大图、多图解决方案,有效避免程序OOM - 郭霖的专栏 - CSDN博客
1.Android ListView工作原理完全解析,带你从源码的角度彻底理解 - 郭霖的专栏 - CSDN博客
2.Android ListView异步加载图片乱序问题,原因分析及解决方案 - 郭霖的专栏 - CSDN博客
3.Android DiskLruCache 源码解析 硬盘缓存的绝佳方案 - Hongyang - CSDN博客
不错的文章:Android高效加载图片和缓存策略LRU,DiskLRU - Houson_c的博客 - CSDN博客
1.Interpolator的几种属性 - Lucky_bo的专栏 - 博客频道 - CSDN.NET
2.Android应用开发之所有动画使用详解 - 工匠若水 - 博客频道 - CSDN.NET
3.animation 坐标参考系 Animation.RELATIVE_TO_PARENT 与 Animation.RELATIVE_TO_SELF - u013578042的博客 - 博客频道 - CSDN.NET
Application
ANR
屏幕横竖屏切换
本人已经改为eclipse样式
alt+Enter键:错误提示快捷键
提取局部变量:Ctrl+Alt+V
提取全局变量:Ctrl+Alt+F
提取方法:Shit+Alt+M
快速找类:Ctrl+Shift+T
查看类的继承关系:F4
查找java文件中的类:Ctrl+O
大写:Ctrl+Shift+X(小写的为Y)
快速复制上面的内容:Ctrl+Alt+向下箭头(选中内容,要不然就默认光标的那一行)
各处搜索:两次shift
搜索指令:Ctrl+Shift+A
关键词搜索:Ctrl+F
查看最近编辑过的文档:Ctrl+E
代码折叠:Ctrl+/Ctrl-
重命名:Shift+Alt+R
搜索Action:Ctrl+Shift+A
eclipse快捷键 包括查找类、方法、变量 - chushoutaizhong的博客 - 博客频道 - CSDN.NET
做完以上书籍就意味着你的Android基础告一段落啦,但还需要更加努力在Android海洋里面遨游,这里建议你接下来学习自定义view:尚硅谷自定义View学习笔记-小白到实战 - CSDN博客