开发
设计步骤
- 业务分析
- 画ui
- 根据ui业务逻辑
数据
封装在JAVABEAN里再加入到列表中
类
常见操作抽出为工具类
界面
一个应用一个图标很少多个
国际化 i18n
在res创建不同国家语言环境集目录 目录时固定写法values-xx
- zh 中文
- en 英文
- 技♂巧:可以在浏览器Internet设置的语言里面看语言环境
异常
异常:没要求直接抓Exception,若公司有要求再抓小的
E/dalvikbm-heap(27767):Out of memory on a 108-byte allocation 内存溢出
W/System.error(1638):android.os.NetworkOnMainThreadException 安卓4.0后 主线程不能连接网络
W/System.err(1708):android.view.ViewRootImpl$CalledFromWrongThreadException:Only the original thread that cteated aview hierarchy can touch its views. 只有主线程才可以更新ui
报错误不是都是错误,有些是警告
虚拟机配置
VM heap 每个android应用分配的空间
包名用公司
CPU选择:看主机 Intel 选 Intel,其他选ARM(慢!)
Snapshot休眠 建议不选
Wipe user data 恢复出厂设置
稳定:4.1.2版本 2.3版本
模拟发短信不能中文
模拟漫游等…
ctrl+F11 横竖直屏切换
颜色设置:#数字
weight 根本布局而充当X或Y的比例,要相应设置另一个方向的
#样式/主题
res/values/下任务文件下定义,一般在styles
样式作用于控件
主题作用于activity或application
抽取样式
抽取相同属性
application
方便修改
< style name = “my_style(样式名称)”>
< item name = “android:layout_width(属性名)”>wrap_content(属性值)
…
mainfest
versionName 版本号
label 标题
Mainfest
xmlns:android = “xxx” 命名空间
< application >
应用
icon 指定activity的图标
screenOrientation = “xxx” xxxx为protrait 竖屏 landscape 横屏
launchMode = " "
- stander
- singletop 任务栈会检查任务栈的栈顶元素,相同则栈顶复用(e:浏览器书签)
- singletask 调用已经加入任务栈的元素时清空其上面的所有元素()唯一实例,检查当前任务栈(e:browers)
- singleinstance 系统自动另外创建任务栈,在新任务栈中只有一个实例 任务栈的位置会随调用改变 (e:phone) 用于activity需要占用大量的系统资源
程序入口
启动界面
aa/bb 自己定义 对应intent.setType(“aa/bb”)
使用intent.setData()时就必须为(Uri.parse(“a:”+xxxx)) 不setData也可通过
android:priority = “x” x为int类型,推荐-1000到1000
优先级
事件类型为sd卡移除(MOUNT)和载入(UNMOUNT)相关:
事件类型为APP包的安装卸载:<data android:scheme=“package”
authorities = “xxx” 必须有
adb
kill-server 杀死adb服务
start-server 开启服务
install xxx,apk 安装apk
uninstall 包名 卸载apk
shell 进入终端
push 文件路径 路径 将文件从电脑复制到手机
pull xxx 文件从手机复制到cmd当前目录下
任务栈
任务:打开一个页面,并进栈
进栈:打开一个Activity
出栈:关闭一个Activity
我们操作的Activity永远时栈顶的Activity
用来维护操作体验
退出栈清空
一般一个应用程序对应一个任务栈
意图 Intent
Intent intent = getIntent() //获取开启这个activity的意图
intent.putExtra(key,value);
.getxxxExtra() //xxx为数据类型
隐式意图
通过设置动作,数据
Intent intent = new Intent();创建一个意图
intent.setAction(Intent.ACTION_CALL);//设置动作
intent.setData(Uri.parse(“tel:”+bumber));//设置拨打的数据
startActivity(intent);//开启意图
.addCategory()//设置category
.addCategory(“android.intent.category.DEFAULT”);
.setType() //设置类型 调用后会自动清除setData的内容
.setData() //设置数据 调用后会自动清除setType的内容
.getType()
.getData()(一般不用后面两种传递数据)
Uri data = intent.getScheme();
String scheme =data.getScheme(0 //过滤器中data的数据都可以
.setDataAndType(data,type)
开启系统应用用隐式,不安全
显式意图
通过设置包名和类名
Intent intent = new Intent(this,Test3Activity.class);
intent.setClassName(“com.itheima.newactivity”,“com.ithema.newactivity.Text3Acitivity”)
或
Intent intent = new Intent(this,Test3Activity.class)
开启自己应用的界面用显示,安全
结束Activity时返回数据
Intent intent = new Intent();
intent.putExtra(“phone”,phone);
setResult(10,intent);
获取intent包中的数据
.getIntent.getExtras().get(“xxx”);
监听
三种方法
-
内部类
-
匿名内部类(前两种用于少量按钮)
-
用当前类实现OnClickListener接口,然后在事件里写入判断哪个控件并实现对应方法(适合多按键)
-
在按钮布局加上onClick属性指向Activity里定义的一个方法(写demo或调试时快速添加按键)
onClickListener的方法重写
@overload
public void onClick(View v){}
android动画 anim
帧动画
api参考:Drawable Animation
Drawalbe
在res下创建drawable目录创建animation-list的xml文件,名字自己取
android:onshot = " " ture为全部显示一次,false为循环执行
使用方法
可以用子线程画UI
ImageView rocketImage = (ImageView) findViewById(R.id.iv); //显示动画
rocketImage.setBackgroundResource(R.drawable.my_anim);//将 xml文件设置为背景资源
AnimationDrawable rocketAnimation = (AnimationDrawable) rocketImage.getBackground();//获取AnimationDrawable类型
rocketAnimation.start(); //开启动画
兼容低版本:设置背景资源后启用线程线程休眠一会后执行后面的内容
规则
android所有控件第一个字母都时大写
测试
根据是否知道源代码
- 黑盒(不知代码,功能测试)
- 白盒(知道代码,写测试代码)
根据测试粒度
- 方法测试(针对方法)
- 单元测试
- 集成测试(集成一起)
- 系统测试
根据暴力成都
- 压力 12306
adb shell中 用
monkey 2000(狂点各个应用2000次)
- 冒烟 基本功能测试
单元测试
创建方法1:
- 要测试类继承AndroidTextCase
- 清单文件配置配合单元测试.png使用
创建方法2:
直接创建 text project ,选择要测试的项目
logcat
过滤器
添加过滤器:
- 加号
- 名字
- 过滤内容,可以只填下面内容中的一个,在过滤器中就只得到该内容
Context
传递上下文(即传递环境)
FileInputStream fis = context.openFileInput(“info.txt”)
获得上下文:getApplicationContext() this
谷歌提供的全局环境框架,new就脱离类,context为空
this
继承context 子类
对话框只能用this
getApplication()
返回context 父类
MENU
onMenuOpened方法重写 返回false可以屏蔽系统创建的菜单
创建方法一(静态)
重写Activity相关方法
onCreateOptionMenu 创建时调用
onOptionItemSelected 点击时调用
resmenu下创建布局,在onCreateOptionMenu中用打气筒生成
创建方法二(动态)
重写Activity相关方法
onCreateOptionMenu 注释掉打气筒,用menu.add添加一个一个菜单项
SharePreferences 或 sp
保存密码用户名
存储步骤
- 获取sp实例
getSharedPreferences(“config”,0) "config"会帮助生成xml文件 0是模式
- 获得sp编辑器
Editor edit = sp.edit()
edit.putString(“name”,name)
- 把edit提交
edit.commit();
##取出步骤 - 获取SP实例
- 取出数据 String name = sp.getString(“name”,"") ""为找不到返回的默认值
- et_name.setText(name)
#XML文件序列化
转换为xml格式
###标准xml格式
xml严格区分大小写
文件头 <?xml version=... encoding=,,,?>
根节点 如…
节点同根节点
制作xml文件
- 用BufferString组拼
StringBuffer sb = new StringBuffer();
sb.append("") //头
sb.append(“xxxx”) //根节点
- XMLSerialize方法生成(官方推荐)
XmlSerializer serializer = Xml.newSerializer();//获得实例(通过Xml工具类)
创建file和FileOutputStream
serializer.setOutput(fos,“utf-8”)//输出文件
serializer.startDocument(“utf-8”,true);
serializer.startTag(null,“smss”)//节点
…
serializer.endTag(null,“smss”)//节点
serializer.endDocument(“utf-8”,true);
##解析xml
- 获取实例
XmlPullParser pullParser = Xml.newPullParser();
- 设置参数
parser,setInput(in,“utf-8”)
- 获取事件类型 详情看api
- 细节:写方法时先给准备实例的变量赋予null,在开始根节点处创建列表对象,在下一级节点创建类对象
- 获取属性
String id = parser.getAttribureValue(0)
channel.setId(id)
…
String city =parser.nextText()//获取两标签间的值
getContentView(R.layout.acivity)//获得上下文
InputStream inputStream = getAssets().open(“weather.xml”) //通过上下文获得资产并以流的形式打开
int i = parser.getEventType();
while(type!=XmlPullParser.END_DOCUMENT){
switch(type)
case XmlPullParser.START_TAG:
case XmlPullParser.equals(parser.getName())
}
.nextText获取接下来的text,指针也移动
sqlite
用于 有大量相似结构的数据(查询速度快)
图形化工具:SQLite Expert Professional
数据库名-journal的文件是临时文件,不用管
能升级但不能降级
创建
SQLiteOpenHelper 负责创建和管理
创建类继承 SQLiteOpenHelper 并创建一个构造函数
如:
public MyOpenHelper(Context context){
super(context ,“itheima.db”,null,1)
}
打开或创建数据库,第一次使用为创建
SQLiteDatabase saLiteDatabase = myOpenHelper.getWritableDatabase();
或
myOpenHelper.getReadableDatabase();//磁盘满了则返回只读对象
onCreate(SQLiteDatabase)方法在只在数据库创建时调用,适合做表结构初始化
public void onCreate(SQLiteDatabase db){
db.execSQL(“create table info(_id integer primary key autoincrement,name varchar(20))”);//SQLite:id 推荐用_id命名 底层以String形式存储,超过范围也没关系
}
创建后会多出一个android_metadata的表,不用管
创建后会多出一列RecNo
当数据库版本升级的时候
id时第0列
打开
SQLiteDataBase db = SQLiteDataBase.openDataBase(“data/data/com.itheima.db/databases/account.db”,null,SQliteDataBase_OPEN_READWRITE)//获取实例
onUpgrade
public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion){}
适合做表结构更新
SQl语句
增加 insert into info(name,phone) values(‘王五’,‘1399999999’);
删除 delete from info where name = ‘王五’
更新 update info set phone = ‘1399999999’ where name = ‘王五’;
update info set phone = phone - 100 where name = ‘王五’;//在语句中运算
选择 select name,phone from onfo;
?:占位符
缺点:容易写错
使用
sql语法
- 打开
- db.execSQL(“insert into info(name,phone) values(?,?)”,new Object[“张三”,“1388888”])//执行
使用完要关闭(可能公司没要求,频繁开关效率低)
获得数据的位置信息
Cursor cursor = db.rawQuery(“select * from info”, null);
String name = cursor.getString(1);//1为第2列,第一列为id
缺点:容易写错,执行sqL语法没有返回值 不容易进行判断
优点:多表查询
API封装
增加
ContentValues values - new ContentValues();
values.put(“name”,“王五”);
…
db.insert{“info”,null,values};
删除
int delete = db.delete(“info”,“name=?”,new String[]{“王五”});//"name= ?"格式
更新
db.update(“info”,values,“name=?”,string[]{“王五”})
查找
Cursor cursor = db.query(“info”,new String[]{“phone”},“name=?”,new String[]{“王五”},null,null,null);
优点:简单 有返回值方便开发
缺点:如果有多个表,不容易查询
sqLite3
安卓默认存储方式时UTF-8
系统应用的数据库 com.android.providers
事物
执行一段逻辑,要么同时成功,要么同时失败
开启事物:
db.beginTransaction();
try{
…
db.setTransactionSuccessful();//给当前事物设置一个成功的标志
}finally{
db.endTransaction();//关闭事物,如过没有成功,自动回滚
}
Cursor
.getCount() 获得行数
,getColumnCount() 获得列数
用完关
SmsMessage
获得实例
SmsMessage smsMessage = smsMessage.createFromPdu()
获取短信内容
String messageBody = smsMessage.getMessageBody();
获取发送者
String address = smsMessage.getOriginatingAddress();
ListView
布局中定义ListView
fastScrool…=“true” 显示滚动条
maxLines = “2” 最多几行
layout_height = “wrap_content” 会执行父高/条目高并向上取整
- match_parent 只调用getCount的次数
定义ListView数据适配器
继承ListAdapter的实现类
getCount() 一共有多少条数据要显示
getItem(int)指定位置的对象
getItemId(int) 获取指定位置的ID
getView()获取一个显示listview的数据的View 会作为listview的一个条目出现
- convertView 历史缓存对象
- 使用时如果超过屏幕,拖动时才创建未显示的对象,自动销毁不用显示的对象,拖动过快时可能会造成内存溢出
- 显示新条目时自动调用
if(convertView == null){
//创建新的view对象
tv = new TextView(MainAcitivty.this);
System.out.priintln(“创建新的view 对象—”+position);
}else{
tv = (TextView) converView
}
条目的布局
- 创建布局文件进行布局 (如起名item)
显示原理
MVC
- M:mode 数据 javabean
- v:view 视图 listview
- c:controller adapter
ArrayAdapter
创建
ArrayAdapter adapter = new ArrayAdapter(this,R.layout.item,objects) //该item布局只有<?xml…> 和 的
用于显示简单文本
SimpleAdapter
创建
SimpleAdapter adapter = new SimpleAdapter(getApplicationContext(),xxx,new String[]{“name”,…},new Int[]{R.id.tv_name,…})
BaseAdapter
用得最多
使用适配器
ListView lv = (ListView) find ViewById(R.id.lv);
lv.setAdapter(new MyListAdapter());
autoCompleteTextView
用法同listView
用于输入提示
布局里
completionThreshold = 输入几个字符才有列表
补间动画
不会改变控件的真实坐标
AlphaAnimation
new xxx(1.0f,0.0f)从不透明到透明
.setDuration(时间)
.setRepeatCount(重复次数)
.setRepeatode(重复模式的常量)
view.setAnimation(xxx的变量名) view是显示动画的控件ImageView
RotateAnimation
构造函数第二个X,Y为旋转的中心
ScaleAnimation
TranslationAnimation
.setFillAfter() 位移结束后是否停留在位移后的地方
AnimationSet
new xxx(true)
.addAnimation(x); x为补间动画
用xml
在res下的anim包下创建alpha.xml
-
定义xml
<alpha 属性=“” 。。。。
pivotX=“50%” //相对于自己 "50%p"相对于父窗口 -
在代码中使用
Animation aa = AnimationUtils.loadAnimation() //用法与intent相似
iv.startAnimation(aa)
contentProvider 内容提供者
将私有数据库等待内容暴露出来
在拥有私有数据库的应用中使用
在logcat中找 pub 有 pub.xxxxxx 说明发布成功
自己的数据库少用,用于谷歌的数据库
创建
创建继承的类
配置mainfest
发布
- 定义一个UriMatcher sURIMatcher = new UriMather(UriMatcher.NO_MATCH)
- onCrate方法创建OpenHelper对象,直接用getContext()获取上下文传递给OpenHelper
- 定义静态代码块
static{
sURIMatcher.addURI(xxx(mainfest中的authorities一样),“query”(随便作),QUERYSUCESS(任意常量)) //URI 相当于 content://XXX/query
}
3.重写的query方法的功能
int code = sURIMatcher.match(uri) //uri和addURI的进行匹配并返回匹配码
if(code == QUERYSUCESS){
SQLiteDatabase db = myOpenHlper.getReadableDatabase();
cursor db.query(“info”,projection(列),selection(条件),selectionArgs(查询条件的参数),null,null,sortOrder)//都是query方法的参数
return cursor; //不能关cursor
}
读取
- 拿到解析者
Uri uri = Uri.parse(“content://xxx/query”);
Cursor cursor = getContentRsolver().query(uri,);
ContentObserver
注册内容观察者
getContentResolver().registerContentObserver(uri,false,new MyContentObserver(new Handler)) //false确切的uri true前缀满足
…
private class MyContentObserver extends contentObserver{//定义一个内容观察者public MyContentObserver(Handler handler){
super(handler);}
public void onChange(boolean selfChange){//当内容发送改变的时候调用
…
super.onChange(selfChange)
}
}
被操作者自己发送一条消息
getContext().getContentResolver().notifyChange(uri.null)
activity
后退按键
public void onBackPressed(){super.onBackPressed();
}
返回结果
通过该activty启动的activity结束时返回结果
protected void onActivityResult(int requestCode,int resultCode,Intent data){
super.onActivityResult(requestCode,resultCode,data);}
方法
onResume 获得焦点
onPause 失去焦点
onDestory 销毁
onCreate 创建
onStop 不可见
onStart 可见
onResart oncreate后第二次start //很少使用
横竖屏切换时会销毁后重新创建
Fragment
API:Activity下的fragment
有自己的生命周期
- onAttach() 依附到Activity
- onCreate() 必须重写 创建时
- onCreateView() 第一次画UI
- onActivityCreated() onCreateView方法里的view都创建完成时调用
- onResume()
- onPause()
- onStop()
- onDestroyView()
- onDestroy() 经常重写
- onDetach() 取消依附
泛型:
onCrateView 可以加载自己的布局
view view = inflate…
return view //这样才能获取到里面的控件,直接return inflate… 不能
name属性指定一个我们自己定义的fragment
-
获取管理者:getFragmentManager()
-
FragmentTransaction beginTransaction = fragmentManager.beginTransaction(); //开启事物
提交事物 -
执行任务
beginTransaction.replace(android.R.ID.LL_LAYOUT,new WxFragment()); //将一个其他布局格式的代码的替换成Fragment -
beginTransaction.commit();
不能在Fragment布局里添加点击事件,必须通过ID添加点击事件
兼容低版本(11前):用v4包的Fragment
- activity必须继承FragmentActivity
- getFragmentManager() 改为 getSupportFragmentManager()
不知怎么归类
查看SD卡空间:
File file = Enviroment.getExternalStorageDirectory();
long totalSpace = file.getTotalSpace();//总大小
long usableSpave = file .getUsableSpave();可用大小
如果报错时API需要更高安卓版本才能使用,可以修改清单的版本,也可用@SuppressLint(“NewApi”)在方法上方屏蔽掉
转换空间大小格式(转化为最佳显示形式):
Formatter.formatFileSize(this,totalsize);
formatter.formatusableSpace = Formatter.formatFileSize(this,totalSpace)
getfiledir() 使用后会创建一个file目录 清除file时删除
getCacheDir() 谷歌提供的缓存目录 清除Cache时删除
Environemt
sd卡环境工具类
获取sd卡路径:
Environment.getExternalStorageDirectory().getPath();
SD卡状态:Environmet.MEDIA_MOUNTED sd卡移除状态
Environment.getExternalStorageState()
好用的API
TextUtils.isEmpty(String) 判断字符串变量是否为空
获取打气筒常用API
- View.inflate(xx,xx,xx)
- LayoutInflater.from(xxx).inflate(xx,xx)
- LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.item,null);
httpurlconection
在java包里
用于发送或接收数据
可以自定义来满足要求,适合高保密的时候
- 获取实例
String path =xxxx
URL url = new URL(path) //有异常,需要抓异常
- 拿到对象 用于发送或者接收数据
HttpURLConnectiong conn = (HttpURLConnction) url.openConnection();//
- 设置发送get请求
conn.setRequestMethod(“GET”);//get要求大写 默认就是get请求
- 设置请求超时时间
conn.setConnectTimeout(5000);
- 获取服务器返回的状态码
int code = conn.getResponseCode();
- 判断是否成功
if(code == 200)
- 获取返回的数据流
InputStream in = conn.getInputStream();
- 使用数据
conn.setRequestProperty(key,value) key 头信息的项 value项的值 请求头
conn.setDoOutput(true) //设置标记允许输出
conn.getOutputStream().write(data.getbytes); //将请求体以流形式提交
如果GET发送中文,需要用URLEncoder()
URLEncoder.encode(name,“utf-8”)
conn,getContentLength() 获取文件大小
进程
API:processes and threads
前台:相当于activity 执行onResume
可视:onPause
服务:startService启动服务
后台:onStop
空:没有维持任务组件
定义四大组件方式一样
服务 service
onCreate 第一次开启
onStartConmand(Intent intent,int flags,int startId) 开启必用
onBind(Intent intent){} 绑定时调用,启动时慢于onCreate执行,只有一次
onUnbind 解除绑定时调用
onDestroy 完全关闭时调用
和线程的区别: activity不可见后,优先级高(服务进程和空)
开启后在后台长期运行 直到用户手工停止
开启
方式1:startService(intent)
方式2:
bindService(intent,new Myconn(),BIND_AUTO_CREATE)
…
private class Myconn implements ServiceConnection{//监视服务的状态的类
public void onServiceConnected(ComponentName name,IBinder service){}//服务连接成功调用 onBind返回NULL时不执行
public void onServiceDisconnected(ComponentName name){}//失去连接调用}
activity执行onDestroy前要unbindService()解绑,不能多次解绑
通过绑定的服务在设置页面不可见
bindService解决上下文脱离问题,调用服务方法
混合
必须先startService,再bindService方法,ondestroy调用unbindService 解绑,结束时再使用stopService
调用服务方法
在服务中添加
创建IBinder
public class MyBinder extends Binder{
public void callBanZheng(…){
…
要调用的服务里的方法}
onBinder里面返回一个new MyBinder() 是 Binder的子类}
在onServiceConnected(xxx)
{
myBinder(MyBinder)service;
}
用MyBinder调用方法
私有类可以用公有接口暴露出里面的部分方法,但在使用时要创建接口类型的对象,父类引用指向子类对象
aidl
进程间通信 IPC
本地服务
运行在自己应用的服务
远程服务
运行在其他应用的服务
- 接口文件改用 .aidl类型
- public去掉
- 自己定义IBinder,直接继承Stub
- 保证2文件aidl文件时同一个且所在包名相同
- 获取IBinder
在onServiceConnect方法中
iservice = stub.asInterface(service)
- 设置action和过滤器
线程
不能在TimerTask里更新UI
四大组件全运行在主线程中,不能做耗时操作
与进度相关的控件 都可以在子线程更新UI
anr
Application not response 应用无响应
主线程(UI线程)中进行类耗时的操作:连接网站,大数据等
headler
自己发,自己处理
子线程:
- 主线程实例化
- 重写handle实例 中的 handlemessage
- 创建Message对象
Message msg = new Message();
msg.obj = content;//该content为String 只能传递一个数据
msg.what 传递int类型
在handleMessage中用msg.xxx与传入时相同来获取
/传递多条数据
msg.setData(bundle) //传递bundle
- 子线程发送信息,发送后handleMessage方法就会执行
hadler.sendMessage(msg)
.postDelay(,)延时发送
LOOPER
主线程创建就有了
内有消息队列,调用headler的消息处理的方法
message
new messaga() 或 .obtain()效率高
msg.what = 1// 也可以定义个常量,处理的时候用switch分析
runOnUIThread
UI线程中立即执行,子线程中发送到消息队列
仅仅更新UI时使用
runOnUIThread(new Runnable{
public void run () {
…
}})
View
findViewById() 时在调用处的当前布局下查找
view = view.inflate(…)
…
TextView tv_name = (TextView) view.findViewById(…)//在view控件下查找
控件属性封装成AttributeSet对象
控件自己的类中写修改自己属性的方法
class MySmartImage extends
MySmartImageView.this.setImageBitmap(bitmap);
layout_gravity = “top” 相对于父
gravity = “top” 相对于自己
布局:style ="@style/my_style(样式名)"\
设置点击事件
.setOnxxxxx(new OnItemClickListener(){
public void onItemClick(AdapterView<?> parent,View view, int position,long id){ //id一般用不到}
})
设置触摸事件
.setOnTouchListtener(new OnTouchListener(){
方法(xxx){
event.getAction();//获取事件类型,在MotionEvent里有定义常量 .ACTION_MOVE 移动 .ACTION
event.getX() //获取X坐标
…
return true //处理完 false未执行完
}
})
ViewGruop
在自己的内部可以有widget
五个布局都继承自ViewGroup
ScrollView
只能有一个子控件,但这个子控件如果也是ViewGroup, 可以有多个子控件
不能水平滚动
RadiGroup
.getCheckedRadioButtonId() //获得选中的radioButton的ID
TextView
ellipsize=“start” 在开头增加… "end"在后面
Toast
属于View
ProgressBar
.setMax(x)最大范围
.setProgress(x)当前值
imageview
要放置位图(bitmap)
在布局文件中使用时调用两个参数构造方法
使用BitmapFactory工厂类生成bitmap
.decodeResource(getResources(),R.drawable.tomcat);
.setBackgroundResouce() 可以接收一个int类型并作为背景
Drawlayout
在布局中的节点为android.support.v4.widget.DrawerLayout
是一个布局,可作为根节点
真实侧滑栏为设置了layout_gravity的view
侧滑栏的布局要放在主显示页面之后
LinearLayout
.add(View)
.removeAllViews(); 清除里面所有VIEW
对话框
alertDialog.Builder builer = new Builder(getApplicationContext());
builder.setTitle(“xxx”);
…(哪种类型,补充)builder.show() //必须要
普通
builder.setMessage(“xxx”)
builder.setPositiveButton(“haha”,new //确定按钮onClickListener(){
public void onClick(DialogInterface dialog, int which){}
})
builder.setNegativeButton(“xx”,xx)
单选
builder setSingleChoiceItems(items(字符数组),-1(没有条目被选中),listen)
多选
builder setMultiChoiceItems(items(字符数组),checkedItems(布尔数组条目是否被选中),new onMultiChoiceClickListener(){
public void onClick(DialogIterfacedialog,int which,boolean isChecked){
dialog.dismiss(); //关闭对话框
}
})
可以添加按钮,按普通的形式添加
进度条
ProgressDialog dialog = new ProgressDialog(this);
dialog.setTitle(“xxx”)
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);//设置进度条样式
dialog.show();
到位置100自动关闭
surfaceview
显示视频
先布局中添加SuffaceView控件
广播 broadcastReceiver
android系统内部已经定义好了一些广播事件 外拨电话 短信到来等,使用broadcastReceiver去接收
需要权限
开启activity前需要添加一个标记 任务栈标记
intent.setFlags(intent.FLAG_ACTIVITY_NEW_TASK)
要求:
- 4.0要求第一次安装应用必须有界面,广播才能生效
- 在设置页面有一个强行停止的按钮,用户点击类 强行停止按钮
注册广播接收者
动态:通过activity的代码中用代码注册,activity销毁的时候要取消注册,退出程序后不能使用接收者,如果要退出后继续使用,要搭载在server
screenReceiver = new ScreenReceiver();
InScreenReceivertentFilter filter = new IntentFilter()
filter.addAction(“XXX”) XXX为要注册的Action
registerReceiver(screenReceiver,filter)//注册
…
unregisterReceiver(screenReceiver);
静态:通过recriver tag 节点静态发布,退出程序后能继续使用接收者
创建
- 新建类
public class OutGoingCallReceiver extends BroadcastReceiver{}
- 配置mainfest文件,添加receiver
- 重写方法,接收到广播时调用
public void onReceive(Contexxt context,Intent intent)
- String currentNumber = getResultData();//获取数据
- setResultData(String) //设置数据
- String action = intent.getAction() //获取事件类型
无序广播
不可以中止,不可以修改
发送
intent.setAction(“com.itheima.custom”)
sendBroadcast(intent)
接收
创建广播接收者onReceive接收方法
有序广播
传播有先后顺序,中间能修改数据,能终止
发送
sendOrderedBroadcast(intent,null(接收权限),null(最终接收者),null(handler),1(初始化码),“xxxxx”(初始化数据),null(额外的数据)) //最终接收者不需要配置mainfest,可以直接new 且不会被中止
接收
String content = getResultData();
.abortBroadcast(); //终止广播
特殊广播接收者
操作特别频繁的广播事件 (e:屏幕的锁屏和解锁 电池电量的变化) 在清单文件里注册无效
需要动态注册
可以用service动态注册长期有效
欺骗手机更新图库等
intent.setAction(Intent.ACTION_MEDIA_MOUNTED);
intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
sendBroadcast(intent);
功能API
发送短信
SmsManager gsm包下的已经过时 用telephony里的
获得实例
.getDefault()
发送
.sendTextMessage(号码,null(服务中心号码),content(发送的内容),null(广播接收者,成功的报告),null(失败的报告));//收费 内容中文不能超过70,英文不能超过140
过长时
ArrayList divideMessages = smsManager.divideMessage
for(String didv : divideMessages){
.sendTextMessage(号码,null(服务中心号码),didv(发送的内容),null(广播接收者,成功的报告),null(失败的报告));
}
TelephonyManager
先创建service的文件,配置service再写
telephonyManager tm = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
tm.listener(new MyPhoneStateListener(),PhoneStateListener.LISTEN_CALL_STATE)
…
private class MyPhoneStateListener extends PhoneStateListener{ //用来监听电话状态public void onCallStateChanged(int state(TelephonyManager里的常数),String inComingNumber){}
}
CALL_STATE_IDLE 空闲状态
CALL_STATE_OFFHOOK 接听
CALL_STATE_RINGING 响铃
MediaRecorder
recorder = new 一个
.setAudioSource (MediaRecorder.AudioSource.VOICE_CALL) //音频来源
- MIC 录单方
- VOICE_CALL 录双方 (中国不违法,美国违法)
.recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP) //输出格式
.recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB) //编码方式
.setOutputFile(“xxx”) //存放位置
.prepare() //准备录 要抓异常
.start() //开始录
,stop() //结束
.seekTo(position)
.setOnxxxListerner() 完成 准备。。。的监听
使用顺序如上
开源项目
用源码
com拷贝到当前工程
用jar包
拷贝.jar到工程的libs
在布局用开源项目的控件时需要带包名+类名
smartimageview
xutils
HttpUtil http = new HttpUtils()
http.download(path,path,true,{ //true为是否支持续传
@Override
public void onSuccess(ResponseInfo responseInfo){}
@Override
public void onFailure(HttpException error,String msg){}
@Override
public void onLoading(long total,long current,
boolean isUploading){//total代表总进度 current 代表当前进度}
})
httpclient
已经封装在安卓中
在子线程
了解就行,没人用
- 获取实例
DefaultHttpClient client = new DafaultHttpClient(0
get
- 准备GET实例
HttpGet get = new HttpGet(path)
- 执行GET请求
HttpResponse response = client.execute(get)
post
- 准备POST实例
HttoPost post = new HttpPost(path)
- 准备parameters
list lists = new Arraylist
- 准备NameValuePair
BasicNameValuePair nameValuePair = new BasicNameValuePair(“username”,name)
- 添加到lists
- 准备entity
UrlEncoderFormEntity emty = new UrlEncodedFormEntity
-
执行POST请求
-
获取返回的状态码
int code = respoonse.goStatusLine().getStatusCode()
- 获取服务器返回的数据 以流的形式返回
InputStream content = response.getEntity().getContent
asyncHttpClient
不需要开子线程
get
- 创建astnchttpclinet 直接new
- 进行get请求
clinet.get(path,new AstncHttpResponseHandler(){
@Override
public void onSuccess(int statusCode,Header[] headlers,bytep[] responsdBody){]//请求成功的回调方法
@Override
public void onFailure(int statusCode,Header[] headlers,bytep[] responsdBody){]//请求失败的回调方法
})
POST
- …
- 准备请求体
RequestParams params = new RequestParams()
params.put(“username”,name)
- 进行POST请求
client.post(path,params,new asyncHttpresponseHandler(){})
vitamio
在工程右键improt vitamio工程
自己的项目右键prorexxxx里的android导入该library
里面有videoView
要在布局里面添加该包的videoView
一定要在清单文件初始花InitActivity
<activity android:name=“io.vov.vitamio.activity.InitActivity”"
- 有LivsChecker.checkVitomiolibs(this)检查vitamio是否可用
- 找ViedeoView
- 设置路径
- 设置准备的监听,准备完成执行start
- .setMediaController(new MediaController(this))来设置video的控制器
解码原理:使用ffmpeg
图片
颜色
像素*像素大小 + 冗余信息 = 大小
bmp高质量
png高质量,压缩,安卓使用
jpg良好质量,压缩
- 单色 1/8byte
- 16色 1/2byte
- 256色 1byte
- 24位(RGB) 3byte
- 安卓采用ARGB 4个byte
缩放加载
加载高分辨率的图片
- 获取图片分辨率
BitmapFactory.Options options = new Options();
option.inJustDecodeBounds =true; //ture时解码器不去真正的解析位图,但还能获取图片的宽和高
Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/dog.jpg",options);
int imgwidth = options.outWidth;
int outHeight = options.outHeight;
- 获取手机分辨率
windowManager wm =(WindowManager)getSystemService(WINDOW_SERVICE);
Ppint point = new Point();
wm.getDefaultDisplay().getSize(point);
int width = point.x;
int height = point.y;
- 计算缩放比(按大的那一边进行缩放,图片不能超) scale
- 按照缩放比显示控件
options.inSampleSize = scale
- 按照缩放比进行解析位图
options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeFile(“xxx”,options);
- 把bitmap显示到控件上
iv.setImageBitmap(bitmap);
操作图片
不能直接在原图上修改,会报错
创建副本
Bitmap copybiBitmap =Bitmap.createBitmap(srcBitmap.getWidth(),srcBitmap.getHeight(),srcBitmap.getConfig())//创建空白
Paint paint =new Paint(); //创建画笔
Canvas canvas =new Canvas(bitmap) //创建一个画板
.setPixel(20,30,color);
canvas.drawBitmap(srcBitmap,new Matrix(),paint);//画画
操作图片
copybiBitmap.setPixel(20,30,Color.RED); //color.TRANSPARENT 透明
显示
iv_copy.setImageBitmap(copybiBitmap)
处理的API
实际工作不用这些API而用动画
旋转
Matix matrix = new Matrix();
matrix.setRotate(20,srcBitmap.getWidth()/2,srcBitmap.getHeight()/2);
缩放
Matix.setScale(0.5f,0.5f);
平移
matix.setTranslate(30,0);
上面的缩放和平移不能同时作用同一画布
镜面
.setScale(-1.0f,1);
.postTranslate(scrBitmap.getWidth(),0);//post在上一次修改的基础上再次修改,set每次都会覆盖上次的操作
倒影可参考镜面
paint
.setColor(Color.x)
.setStrokeWidth(int) 加粗
Bitmap
.compress(CompressFormat.x,100,)//保存文件x为格式JPG或PNG等, 100为图片质量(0-100)
照相机录像机
容用谷歌API可能发生不兼容
照片png视频MP4
音频
mediaplayer
播放音频和视频
底层实现类创建子线程,不用再创建子线程
视频只能MP4或3gp格式
- new
- mediaPlayer.setDataSource(path);//设置路径,可以本地,可以网络
- mediaPlayer.prepare();//准备(同步)
- mediaPlayer.start();
prepareAsync 异步准备
一般会加个setOnPreparedListener(new xxx){}
.setDisplay
同步:一般播放本地音乐 直到成功
异步:播放网络音乐 不用开子线程 相当于开子线程
.getDuration(); //获取到当前的总长度
seekbar
拖动条
updateSeekBar();
.setOnSeekBarChangeListener(new OnSeekBarChangeList(){
public void onStopTrackingTouch()
- onStartTrackingTouch
- onProgressChanged
})
sufaceView
.getHolder
holder.addCallback(new Callback(){
xxxDestory 方法 surface在不可见时,xxxCreate在可见时调用})
VideoView
在布局中声明
找控件
setxxxPath
.start
是surfaceView的子类
WindowManager
悬浮窗口
-
权限
-
获取
mwManager = (WindowManager)getApplication().getSystemService(Context.WINDOW_SERVICE);
-
设置参数
final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, 0, 0, PixelFormat.TRANSPARENT);
layoutParams.type =WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
layoutParams.x= 600;
layoutParams.y= 600; -
使用
add update remove 三个用法
mwManager.addView(floatPlayer, layoutParams);//实现添加了一个悬浮控件
Motion
杂
谷歌一般以 base defalut simple
systemClock.sleep(ms) 也时可以线程睡眠
SystemClock.uptimeMillis() 当前手机开机时间
sd卡写数据要加权限,读数据不用
复制包后需要修改Manifest里的包名 activity文件重新引入包(引用自己包的R文件) 或是 更简单:Rename Application Package
uri 统一资源标示符 自己定义的路径 想代表什么就代表什么
url 统一资源定位符 www.baidu.com
dp会自动根据屏幕计算
sp:用于给文字设置大小
R文件不会引用assert里的,assert里的必须通过上下文获取
android.R.id.content 代表手机当前屏幕 类似的 android.xxxxxx 是系统定义好了的
raw里的文件命名必须小写英文开头
contentValues
ContentValues 和HashTable类似都是一种存储的机制 但是两者最大的区别就在于,contenvalues只能存储基本类型的数据,像string,int之类的,不能存储对象这种东西,而HashTable却可以存储对象。ContentValues存储对象的时候,以(key,value)的形式来存储数据。
TODO
TOMCAT
847p一半