day_03
0回顾
4.0以上
四层结构
①linux内核
② c/c++函数库
③ application framework 应用框架层
④ 应用层
jvm dvm区别
①编译之后 .class-> .jar .class->dex
② 基于栈 基于寄存器
art dalvik
字节码翻译成机器码时间不同
doc 文档
platformtools adb
source
platform android.jar
src java gen 自动生成 R 生成res目录下资源的相关索引
res 资源
drawable
layout 布局
values->string.xml
dimens.xml
style.xml
Androidmanifest.xml 清单文件
声明了包名 package
打包的过程
① 编译
java->.class->dex
xml相关的生成 resources.resc
不能编译的文件
androidManifest.xml
② 把上述内容变成.zip ->apk
③ 对apk进行签名
④ adb
adb install
adb uninstall
adb push
adb pull
电话拨号器
①写UI ②根据UI写java代码 ③部署测试
TextView Edittext Button
Activity 界面 是一个上下文
oncreate
setcontentView
findviewbyid
setonclicklistener(onclicklistener)
点击事件4中写法
①有名的内部类
②匿名内部类
③ 让activity实现接口
④ οnclick=“call”
获取用户输入 非空判断
调用另外界面打电话 Intent intent = new Intent();
intent.setAction
intent.setData
startActivity(intent);
提示用户 Toast.makeText(上下文,文字,时长).show();
五大布局
LinearLayout orientation vertical Horizontal
RelativeLayout 相对布局
FrameLayout margin 外边距 padding 内边距
TableLayout
AbsoluteLayout 绝对布局 Layout_x Layout_y
1 测试的相关概念
一款好的软件是测出来的不是开发出来的
bug 虫子
①崩溃 崩溃率高于4%
②逻辑上的bug
从代码可见的角度
黑盒测试 自动化测试
白盒测试
从测试的粒度
单元测试
集成测试
系统测试
从暴力程度
压力测试
adb shell 下运行monkey
monkey +次数 monkey -p 包名 次数 点具体某一个应用
冒烟测试
2 单元测试
①写一个类继承 androidtestcase
② 写测试的代码
③运行测试代码之前 需要在清单文件中声明
声明在application节点外
1.
声明在application节点里面
④ 在测试的方法上单击右键 选择 run as->android junit test
3 日志猫的使用 logcat
- //区别 输出颜色不同 级别不同
-
Log.v("MainActivity", "verbose");//黑色的日志
-
Log.d("MainActivity", "debug"); //蓝色的日志
-
Log.i("MainActivity", "info"); // 绿色的日志
-
Log.w("MainActivity", "warning"); //黄色的日志
-
Log.e("MainActivity", "error"); //红色的日志
具体开发的时候 一般会对logcat进行封装
1.public class LogUtils {
2. private static boolean openLog = true;
3.
4. public static void LOGD(String tag,String msg){
5. if(openLog){
6. Log.d(tag, msg);
7. }
8. }
9. public static void LOGI(String tag,String msg){
10. if(openLog){
11. Log.i(tag, msg);
12. }
13. }
14.}
可以通过修改 openLog true或者false控制log的显示还是关闭
4 登录案例 File
新知识点
应用私有路径 data/data/包名/
控件:CheckBox isChecked();
MainActivity.java
1.public class MainActivity extends Activity {
2.
3. private EditText et_username;
4. private EditText et_pwd;
5. private CheckBox cb_isSave;
6. private Button btn_login;
7.
8. @Override
9. protected void onCreate(Bundle savedInstanceState) {
10. super.onCreate(savedInstanceState);
11. //加载界面
12. setContentView(R.layout.activity_main);
13. //找到关心的控件
14. et_username = (EditText) findViewById(R.id.et_username);
15. et_pwd = (EditText) findViewById(R.id.et_password);
16. cb_isSave = (CheckBox) findViewById(R.id.cb_isSave);
17. btn_login = (Button) findViewById(R.id.btn_login);
18.
19. //设置点击事件
20. btn_login.setOnClickListener(new MyListener());
21. //获取用户保存的信息
22. // String[] info = Utils.readInfo();
23. // String[] info = Utils.readInfobyContext(this);
24. String[] info = Utils.readInfoFromSdCard();
25. //如果返回不为空 说明有信息 显示到edittext上
26. if(info!=null){
27. //显示用户的信息
28. et_username.setText(info[0]);
29. et_pwd.setText(info[1]);
30. }
31. }
32.
33.
34. private class MyListener implements OnClickListener{
35.
36. @Override
37. public void onClick(View v) {
38. //当按钮被点击就会走这个方法
39. //①获取用户输入
40. String pwd = et_pwd.getText().toString().trim();
41. String username = et_username.getText().toString().trim();
42. //②判断输入是否为空
43. if(TextUtils.isEmpty(username)||TextUtils.isEmpty(pwd)){
44. //2.1如果为空 Toast提示用户 不能为空
45. Toast.makeText(MainActivity.this, “用户名密码不能为空”, Toast.LENGTH_SHORT).show();
46. }else{
47. //2.2如果不为空 判断是否保存密码
48. //③ 通过checkbox的状态 判断是否保存
49. boolean checked = cb_isSave.isChecked();
50. if(checked){
51. //boolean saveInfo = Utils.saveInfo(username,pwd);
52. //boolean saveInfo = Utils.saveInfobycontext(MainActivity.this,username,pwd);
53. boolean saveInfo = Utils.saveInfo2sdcard(username,pwd);
54. if(saveInfo){
55. Toast.makeText(MainActivity.this, “保存成功”, Toast.LENGTH_SHORT).show();
56. }else{
57. Toast.makeText(MainActivity.this, “保存失败”, Toast.LENGTH_SHORT).show();
58. }
59. //勾选上了 保存用户名密码
60. //Log.d(“MainActivity”, “保存用户名:”+username+“密码:”+pwd);
61. }
62. //④执行登陆的业务逻辑
63. Log.d(“MainActivity”, “开始登陆…”);
64. }
65. }
66. }
67.}
Utils.java
1./**
2. * 保存用户名密码
3. * @param username 用户名
4. * @param pwd 密码
5. * @return 是否保存成功
6. /
7. public static boolean saveInfo(String username, String pwd) {
8. String info = username+"##"+pwd;
9. File file = new File(“data/data/com.itheima.logindemo/info.txt”);
10. try {
11. FileOutputStream fos = new FileOutputStream(file);
12. fos.write(info.getBytes());
13. fos.close();
14. return true;
15. } catch (Exception e) {
16. e.printStackTrace();
17. return false;
18. }
19. }
20.
21. /*
22. * 获取用户保存的用户名和密码
23. * @return 数组的第一个元素是用户名 第二个元素是密码 如果为null说明获取失败
24. */
25. public static String[] readInfo(){
26. File file = new File(“data/data/com.itheima.logindemo/info.txt”);
27. try {
28. FileInputStream fis = new FileInputStream(file);
29. BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
30. String temp = reader.readLine();
31. String[] result = temp.split("##");
32. return result;
33. } catch (Exception e) {
34. e.printStackTrace();
35. return null;
36. }
37. }
布局文件
1.<RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
2. xmlns:tools=“http://schemas.android.com/tools”
3. android:layout_width=“match_parent”
4. android:layout_height=“match_parent”
5. android:paddingBottom="@dimen/activity_vertical_margin"
6. android:paddingLeft="@dimen/activity_horizontal_margin"
7. android:paddingRight="@dimen/activity_horizontal_margin"
8. android:paddingTop="@dimen/activity_vertical_margin"
9. tools:context=".MainActivity" >
10.
11. <EditText
12. android:id="@+id/et_username"
13. android:layout_width=“match_parent”
14. android:layout_height=“wrap_content”
15. android:hint=“请输入用户名” />
16. <EditText
17. android:id="@+id/et_password"
18. android:layout_below="@id/et_username"
19. android:layout_width=“match_parent”
20. android:layout_height=“wrap_content”
21. android:inputType=“textPassword”
22. android:hint=“请输入密码”/>
23. <CheckBox
24. android:id="@+id/cb_isSave"
25. android:layout_below="@id/et_password"
26. android:layout_width=“wrap_content”
27. android:layout_height=“wrap_content”
28. android:text=“勾选保存信息”/>
29. <Button
30. android:id="@+id/btn_login"
31. android:layout_below="@id/et_password"
32. android:layout_alignParentRight=“true”
33. android:layout_width=“wrap_content”
34. android:layout_height=“wrap_content”
35. android:text=“登陆”
36. />
37.
38.
5 使用上下文(Context)获取常见目录
Context 可以理解成大工具类
通过上下文 可以访问跟当前应用相关的 全局信息(系统资源) 也可以访问当前应用的私有资源 和类
也可以做系统级的调用 比如 开启另外一个activity 发广播 开启服务
getFilesDir(); 操作的是 data/data/包名/files
openFileInput->FileInputStream 这两个方法获取的流实际上操作的就是getFilesDir()对应目录下的文件
openFileOutput->FileOutputStream
访问/data/data/包名 这个私有目录 一定要使用上下文获取路径
1.public static boolean saveInfobycontext(Context context,String username, String pwd) {
2. String info = username+"##"+pwd;
3.// File file = new File(“data/data/com.itheima.logindemo/info.txt”);
4. //使用上下文获取应用相关私有路径
5. // File file = new File(context.getFilesDir().getAbsolutePath()+"/info.txt");
6. try {
7. // FileOutputStream fos = new FileOutputStream(file);
8. FileOutputStream fos = context.openFileOutput(“info2.txt”, Context.MODE_PRIVATE);
9. fos.write(info.getBytes());
10. fos.close();
11. return true;
12. } catch (Exception e) {
13. e.printStackTrace();
14. return false;
15. }
16. }
17.
18.
19. public static String[] readInfobyContext(Context context){
20. File file = new File(“data/data/com.itheima.logindemo/info.txt”);
21. try {
22. //FileInputStream fis = new FileInputStream(file);
23. FileInputStream fis = context.openFileInput(“info2.txt”);
24. BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
25. String temp = reader.readLine();
26. String[] result = temp.split("##");
27. return result;
28. } catch (Exception e) {
29. e.printStackTrace();
30. return null;
31. }
32. }
6 登录数据保存到sd卡上
7 获取sd卡可用空间
1.public class MainActivity extends Activity {
2.
3. @Override
4. protected void onCreate(Bundle savedInstanceState) {
5. super.onCreate(savedInstanceState);
6. setContentView(R.layout.activity_main);
7. TextView tv_free = (TextView) findViewById(R.id.tv_freespace);
8. TextView tv_total = (TextView) findViewById(R.id.tv_totalspace);
9.
10. File storageDirectory = Environment.getExternalStorageDirectory();
11. long totalSpace = storageDirectory.getTotalSpace();
12. long freeSpace = storageDirectory.getFreeSpace();
13.
14. //通过formatter把用byte字节表示的大小 转换成用 kb mb gb 这种单位表示的字符串
15. String total = Formatter.formatFileSize(this, totalSpace);
16. String free = Formatter.formatFileSize(this, freeSpace);
17.
18. tv_free.setText(“剩余空间:”+free);
19. tv_total.setText(“总空间:”+total);
20. }
21.}
8 文件权限介绍
9 SharedPreferences介绍
SharedPreferences 轻量级的存储信息的api 可以保存的数据类型有限 六种
boolean int long float String Set
相关api
获取SharedPreferences 实例
getSharedPreferences(“文件名字”,模式); 上下文的api
sp.getXXXX(key,defValue); 第一个参数 取值用到的key 第二个参数 默认值 当用key找具体的值的时候 如果找不到 就会返回默认值;
sp.edit();->Editor
通过Editor对象 可以调用putXXXX(key,value); 修改sp文件
只有调用了editor的commit方法 所有的putXXX才会生效
sp是通过xml文件来保存信息的
- //获取sp对象 第一个参数 sp保存的文件的名字 第二个参数 存储的模式
-
//如果访问的文件不存在 当编辑保存生效之后会创建改文件
-
sp = getSharedPreferences("info", MODE_PRIVATE);
-
boolean isSave = sp.getBoolean("isChecked", false);
-
if(isSave){
-
String username = sp.getString("username", "");
-
String pwd = sp.getString("pwd", "");
-
et_username.setText(username);
-
et_pwd.setText(pwd);
-
cb_isSave.setChecked(true);
-
}
- }
sp会在data/data/包名/shared_prefs/ 保存.xml文件
10 xml序列化
备份短信
SMS
①通过StringBuilder实现 ②通过xml序列化器实现
11 android下xml解析
android表示大小的单位
不要使用px
用dp dp跟像素密度无关的
表示文字大小的要用sp
今日回顾
直接用写死路径的方式保存用户名密码
应用私有路径 data/data/包名/
CheckBox
isChecked();
Context☆☆☆☆☆
getFilesDir();->File 获取到data/data/包名/files
openFileOutput(“要操作的文件名字”,模式); Mode_priate(访问同名文件 覆盖操作) MODE_APPEND(访问同名文件追加内容); FileOutPutStream
openFileInput(); FileInputeStream
Environment.getExternalStorageDirectory();->File 获取到sd卡的路径 ☆☆☆☆
Environment.getExternalStorageState(); ->String 获取sd卡状态 MEDIA_MOUNTED 说明sd卡可用
操作sd卡进行读写的时候 需要一个权限 android.permission.WRITE_EXTORNAL_DIRECTORY;
SharedPreferences ☆☆☆☆☆☆
保存成xml文件 可以保存数据类型 int long boolean float String set
①获取SharedPreferences 对象
getSharedPreferences(名字,模式);
sp.getXXXX(key,defValue);
sp.edit();->editor.putXXX(key,value);
editor.commit();
XMLSeralizer(); ☆☆☆
setOutput(outputStream,encoding);
startDocument();
startTag();
text()
endTag();
endDocument();