Android入门笔记03
测试
黑盒测试
- 测试逻辑业务
白盒测试
- 测试逻辑方法
根据测试粒度
- 方法测试:function test
- 单元测试:unit test
- 集成测试:integration test
- 系统测试:system test
根据测试暴力程度
- 冒烟测试:smoke test
- 压力测试:pressure test
单元测试junit
定义一个类继承AndroidTestCase,在类中定义方法,即可测试该方法
在指定指令集时,targetPackage指定你要测试的应用的包名
<instrumentation android:name="android.test.InstrumentationTestRunner"android:targetPackage="com.itheima.junit"></instrumentation>
定义使用的类库
<uses-library android:name="android.test.runner"></uses-library>
断言的作用,检测运行结果和预期是否一致
如果应用出现异常,会抛给测试框架
SQLite数据库
- 轻量级关系型数据库
- 创建数据库需要使用的api:SQLiteOpenHelper
必须定义一个构造方法:
//arg1:数据库文件的名字//arg2:游标工厂//arg3:数据库版本public MyOpenHelper(Context context, String name, CursorFactory factory, int version){}
数据库被创建时会调用:onCreate方法
数据库升级时会调用:onUpgrade方法
创建数据库
//创建OpenHelper对象
MyOpenHelper oh = new MyOpenHelper(getContext(), "person.db", null, 1);
//获得数据库对象,如果数据库不存在,先创建数据库,后获得,如果存在,则直接获得
SQLiteDatabase db = oh.getWritableDatabase();
getWritableDatabase():打开可读写的数据库
getReadableDatabase():在磁盘空间不足时打开只读数据库,否则打开可读写数据库
在创建数据库时创建表
public void onCreate(SQLiteDatabase db) {// TODO Auto-generated method stubdb.execSQL("create table person (_id integer primary key autoincrement, name char(10), phone char(20), money integer(20))");}
数据库的增删改查
###SQL语句
- insert into person (name, phone, money) values (‘张三’, ‘159874611’, 2000);
- delete from person where name = ‘李四’ and _id = 4;
- update person set money = 6000 where name = ‘李四’;
- select name, phone from person where name = ‘张三’;
执行SQL语句实现增删改查
//插入db.execSQL("insert into person (name, phone, money) values (?, ?, ?);", new Object[]{"张三", 15987461, 75000});//查找Cursor cs = db.rawQuery("select _id, name, money from person where name = ?;", new String[]{"张三"});
测试方法执行前会调用此方法
protected void setUp() throws Exception {super.setUp();// 获取虚拟上下文对象oh = new MyOpenHelper(getContext(), "people.db", null, 1);}
使用api实现增删改查
插入
//以键值对的形式保存要存入数据库的数据ContentValues cv = new ContentValues();cv.put("name", "刘能");cv.put("phone", 1651646);cv.put("money", 3500);//返回值是改行的主键,如果出错返回-1long i = db.insert("person", null, cv);
删除
//返回值是删除的行数int i = db.delete("person", "_id = ? and name = ?", new String[]{"1", "张三"});
修改
ContentValues cv = new ContentValues();cv.put("money", 25000);int i = db.update("person", cv, "name = ?", new String[]{"赵四"});
查询
//arg1:要查询的字段//arg2:查询条件//arg3:填充查询条件的占位符Cursor cs = db.query("person", new String[]{"name", "money"}, "name = ?", new String[]{"张三"}, null, null, null);while(cs.moveToNext()){// 获取指定列的索引值String name = cs.getString(cs.getColumnIndex("name"));String money = cs.getString(cs.getColumnIndex("money"));System.out.println(name + ";" + money);}
事务
保证多条SQL语句要么同时成功,要么同时失败
最常见案例:银行转账
事务api
try {//开启事务db.beginTransaction();...........//设置事务执行成功db.setTransactionSuccessful();} finally{//关闭事务//如果此时已经设置事务执行成功,则sql语句生效,否则不生效db.endTransaction();}
MyOpenHelper.java
package com.example.administrator.myapplication;import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;public class MyOpenHelper extends SQLiteOpenHelper {public MyOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,int version) {super(context, name, factory, version);// TODO Auto-generated constructor stub}//数据库创建时,此方法会调用@Overridepublic void onCreate(SQLiteDatabase db) {System.out.println("数据库创建了");//创建表db.execSQL("create table person(_id integer primary key autoincrement, name char(10), salary char(20), phone integer(20))");}//数据库升级时,此方法会调用@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {System.out.println("数据库升级了");}}
MainActivity.java
package com.example.administrator.myapplication;import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.EditText;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//getContext():获取一个虚拟的上下文
// MyOpenHelper oh = new MyOpenHelper(getApplicationContext(),"people.db", null, 1);//如果数据库不存在,先创建数据库,再获取可读可写的数据库对象,如果数据库存在,就直接打开
// SQLiteDatabase db = oh.getWritableDatabase();//如果存储空间满了,那么返回只读数据库对象
// SQLiteDatabase db = oh.getReadableDatabase();
// insert();select();
// insertApi();deleteApi();}public void insert(){//getContext():获取一个虚拟的上下文MyOpenHelper oh = new MyOpenHelper(getApplicationContext(),"people.db", null, 1);SQLiteDatabase db = oh.getWritableDatabase();db.execSQL("insert into person (name,salary,phone) values(?,?,?)", new Object[]{"小志", 14000, "13888"});db.execSQL("insert into person (name,salary,phone) values(?,?,?)",new Object[]{"小智","13000","13888888888"});//SQLSite是轻量级数据库,数据类型错误也能正常插入,全部都认为是字符串,但是插入String到Integer会变成0db.execSQL("insert into person (name,salary,phone) values(?,?,?)",new Object[]{"小刚",13000,"13888888888"});db.close();}public void delete(){MyOpenHelper oh = new MyOpenHelper(getApplicationContext(),"people.db", null, 1);SQLiteDatabase db = oh.getWritableDatabase();db.execSQL("delete from person where name =?",new Object[]{"小志"});db.close();}public void update(){MyOpenHelper oh = new MyOpenHelper(getApplicationContext(),"people.db", null, 1);SQLiteDatabase db = oh.getWritableDatabase();db.execSQL("update person set phone = ? where name = ?",new Object[]{"小智","13202120201"});db.close();}public void select(){MyOpenHelper oh = new MyOpenHelper(getApplicationContext(),"people.db", null, 1);SQLiteDatabase db = oh.getWritableDatabase();Cursor cursor = db.rawQuery("select name,phone,salary from person",null);while (cursor.moveToNext()){String name = cursor.getString(0);String salary = cursor.getString(2);String phone = cursor.getString(cursor.getColumnIndex("phone"));System.out.println(name+";"+salary+";"+phone);}db.close();}public void insertApi(){MyOpenHelper oh = new MyOpenHelper(getApplicationContext(),"people.db", null, 1);SQLiteDatabase db = oh.getWritableDatabase();ContentValues values = new ContentValues();values.put("name","游戏王");values.put("phone","1952123121");values.put("salary",16000);db.insert("person",null,values);db.close();}public void deleteApi(){MyOpenHelper oh = new MyOpenHelper(getApplicationContext(),"people.db", null, 1);SQLiteDatabase db = oh.getWritableDatabase();int i = db.delete("person","name=? and _id=?",new String[]{"小刚","7"});System.out.println(i);db.close();}public void updateApi(){MyOpenHelper oh = new MyOpenHelper(getApplicationContext(),"people.db", null, 1);SQLiteDatabase db = oh.getWritableDatabase();ContentValues values = new ContentValues();values.put("salary",36000);int i = db.update("person",values,"name=?",new String[]{"小刚"});System.out.println(i);db.close();}public void selectApi(){MyOpenHelper oh = new MyOpenHelper(getApplicationContext(),"people.db", null, 1);SQLiteDatabase db = oh.getWritableDatabase();Cursor cursor = db.query("person",null,null,null,null,null,null,null);while (cursor.moveToNext()){String name = cursor.getString(cursor.getColumnIndex("name"));String phone = cursor.getString(cursor.getColumnIndex("phone"));System.out.println(name+":"+phone);}db.close();}public void testTransaction(){MyOpenHelper oh = new MyOpenHelper(getApplicationContext(),"people.db", null, 1);SQLiteDatabase db = oh.getWritableDatabase();//开启事务try{db.beginTransaction();ContentValues values = new ContentValues();values.put("salary",15000);db.update("person",values,"name=?",new String[]{"小智"});values.clear();values.put("salary",13000);db.update("person",values,"name=?",new String[]{"小志"});//这里做一个运行时异常int i = 3/0;//设置事务执行成功db.setTransactionSuccessful();}catch (Exception e){e.printStackTrace();}finally {//关闭事务,同时提交,如果没有设置事务执行成功则sql回滚db.endTransaction();db.close();}}}
把数据库的数据显示至屏幕
- 任意插入一些数据
定义业务bean:Person.java
读取数据库的所有数据
Cursor cs = db.query("person", null, null, null, null, null, null);while(cs.moveToNext()){String name = cs.getString(cs.getColumnIndex("name"));String phone = cs.getString(cs.getColumnIndex("phone"));String money = cs.getString(cs.getColumnIndex("money"));//把读到的数据封装至Person对象Person p = new Person(name, phone, money);//把person对象保存至集合中people.add(p);}
把集合中的数据显示至屏幕
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);for(Person p : people){//创建TextView,每条数据用一个文本框显示TextView tv = new TextView(this);tv.setText(p.toString());//把文本框设置为ll的子节点ll.addView(tv);}
分页查询
Cursor cs = db.query("person", null, null, null, null, null, null, "0, 10");
activity_main.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:id="@+id/ll"android:layout_width="match_parent"android:layout_height="wrap_content"tools:context=".MainActivity"android:orientation="vertical"></LinearLayout>
</ScrollView>
MainActivity.java
package com.example.administrator.myapplication;import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.example.administrator.myapplication.domain.Person;
import java.util.ArrayList;
import java.util.List;public class MainActivity extends AppCompatActivity {private List<Person> personList;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);personList = new ArrayList<>();MyOpenHelper oh = new MyOpenHelper(getApplicationContext(),"people.db", null, 1);SQLiteDatabase db = oh.getWritableDatabase();Cursor cursor = db.query("person",null,null,null,null,null,null,null);while (cursor.moveToNext()){String _id = cursor.getString(cursor.getColumnIndex("_id"));String name = cursor.getString(cursor.getColumnIndex("name"));String phone = cursor.getString(cursor.getColumnIndex("phone"));String salary = cursor.getString(cursor.getColumnIndex("salary"));Person person = new Person(_id,name,phone,salary);personList.add(person);}db.close();LinearLayout ll = findViewById(R.id.ll);//把数据显示至屏幕for(Person person:personList){TextView tv = new TextView(this);tv.setText(person.toString());//把TextView设置为线性布局的子节点tv.setTextSize(18); //18spll.addView(tv);}}
}
效果演示
ListView
- 就是用来显示一行一行的条目的
- MVC结构
- M:model模型层,要显示的数据 ————people集合
- V:view视图层,用户看到的界面 ————ListView
- c:control控制层,操作数据如何显示 ————adapter对象
- 每一个条目都是一个View对象
BaseAdapter
必须实现的两个方法
第一个
//系统调用此方法,用来获知模型层有多少条数据@Overridepublic int getCount() {return people.size();}
第二个
//系统调用此方法,获取要显示至ListView的View对象//position:是return的View对象所对应的数据在集合中的位置@Overridepublic View getView(int position, View convertView, ViewGroup parent) {System.out.println("getView方法调用" + position);TextView tv = new TextView(MainActivity.this);//拿到集合中的元素Person p = people.get(position);tv.setText(p.toString());//把TextView的对象返回出去,它会变成ListView的条目return tv;}
屏幕上能显示多少个条目,getView方法就会被调用多少次,屏幕向下滑动时,getView会继续被调用,创建更多的View对象显示至屏幕
activity_main.xml
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/ll"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"android:orientation="vertical"><ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent"></ListView>
</LinearLayout>
MainActivity.java
package com.example.administrator.myapplication;import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import com.example.administrator.myapplication.domain.Person;
import java.util.ArrayList;
import java.util.List;public class MainActivity extends AppCompatActivity {private List<Person> personList;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);personList = new ArrayList<>();MyOpenHelper oh = new MyOpenHelper(getApplicationContext(),"people.db", null, 1);SQLiteDatabase db = oh.getWritableDatabase();Cursor cursor = db.query("person",null,null,null,null,null,null,null);while (cursor.moveToNext()){String _id = cursor.getString(cursor.getColumnIndex("_id"));String name = cursor.getString(cursor.getColumnIndex("name"));String phone = cursor.getString(cursor.getColumnIndex("phone"));String salary = cursor.getString(cursor.getColumnIndex("salary"));Person person = new Person(_id,name,phone,salary);personList.add(person);}db.close();ListView lv = findViewById(R.id.lv);lv.setAdapter(new MyAdapter());}class MyAdapter extends BaseAdapter{@Overridepublic int getCount() {return personList.size();}@Overridepublic Object getItem(int position) {return null;}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {TextView tv = new TextView(MainActivity.this);Person p =personList.get(position);tv.setTextSize(18);tv.setText(p.toString());return tv;}}
}
为了显示好看一点
item_listview.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent" ><TextView android:id="@+id/tv_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="名字"android:textSize="25sp"/><LinearLayout android:layout_alignParentRight="true"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"><TextView android:id="@+id/tv_phone"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="号码"/><TextView android:id="@+id/tv_salary"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="工资"/></LinearLayout>
</RelativeLayout>
MainActivity.java
package com.example.administrator.myapplication;import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import com.example.administrator.myapplication.domain.Person;
import java.util.ArrayList;
import java.util.List;public class MainActivity extends AppCompatActivity {private List<Person> personList;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);personList = new ArrayList<>();MyOpenHelper oh = new MyOpenHelper(getApplicationContext(),"people.db", null, 1);SQLiteDatabase db = oh.getWritableDatabase();Cursor cursor = db.query("person",null,null,null,null,null,null,null);while (cursor.moveToNext()){String _id = cursor.getString(cursor.getColumnIndex("_id"));String name = cursor.getString(cursor.getColumnIndex("name"));String phone = cursor.getString(cursor.getColumnIndex("phone"));String salary = cursor.getString(cursor.getColumnIndex("salary"));Person person = new Person(_id,name,phone,salary);personList.add(person);}db.close();ListView lv = findViewById(R.id.lv);lv.setAdapter(new MyAdapter());}class MyAdapter extends BaseAdapter{@Overridepublic int getCount() {return personList.size();}@Overridepublic Object getItem(int position) {return null;}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {Person p =personList.get(position);View view = View.inflate(MainActivity.this,R.layout.item_listview,null);TextView tv_name = view.findViewById(R.id.tv_name);tv_name.setText(p.getName());TextView tv_phone = view.findViewById(R.id.tv_phone);tv_phone.setText("手机号:"+p.getPhone());TextView tv_salary =view.findViewById(R.id.tv_salary);tv_salary.setText("工资:"+p.getSalary());return view;}}
条目的缓存
- 当条目划出屏幕时,系统会把该条目缓存至内存,当该条目再次进入屏幕,系统在重新调用getView时会把缓存的条目作为convertView参数传入,但是传入的条目不一定是之前被缓存的该条目,即系统有可能在调用getView方法获取第一个条目时,传入任意一个条目的缓存
对话框
确定取消对话框
创建对话框构建器对象,类似工厂模式
AlertDialog.Builder builder = new Builder(this);
设置标题和正文
builder.setTitle("警告");builder.setMessage("若练此功,必先自宫");
设置确定和取消按钮
builder.setPositiveButton("现在自宫", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {// TODO Auto-generated method stubToast.makeText(MainActivity.this, "恭喜你自宫成功,现在程序退出", 0).show();}});builder.setNegativeButton("下次再说", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {// TODO Auto-generated method stubToast.makeText(MainActivity.this, "若不自宫,一定不成功", 0).show();}});
使用构建器创建出对话框对象
AlertDialog ad = builder.create();ad.show();
单选对话框
AlertDialog.Builder builder = new Builder(this);builder.setTitle("选择你的性别");
- 定义单选选项
final String[] items = new String[]{"男", "女", "其他"};//-1表示没有默认选择//点击侦听的导包要注意别导错builder.setSingleChoiceItems(items, -1, new OnClickListener() {//which表示点击的是哪一个选项@Overridepublic void onClick(DialogInterface dialog, int which) {Toast.makeText(MainActivity.this, "您选择了" + items[which], 0).show();//对话框消失dialog.dismiss();}});builder.show();
多选对话框
AlertDialog.Builder builder = new Builder(this);builder.setTitle("请选择你认为最帅的人");
- 定义多选的选项,因为可以多选,所以需要一个boolean数组来记录哪些选项被选了
final String[] items = new String[]{"赵帅哥","赵师哥","赵老师","侃哥"};//true表示对应位置的选项被选了final boolean[] checkedItems = new boolean[]{true,false,false,false,};builder.setMultiChoiceItems(items, checkedItems, new OnMultiChoiceClickListener() {//点击某个选项,如果该选项之前没被选择,那么此时isChecked的值为true@Overridepublic void onClick(DialogInterface dialog, int which, boolean isChecked) {checkedItems[which] = isChecked;}});builder.setPositiveButton("确定", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {StringBuffer sb = new StringBuffer();for(int i = 0;i < items.length; i++){sb.append(checkedItems[i] ? items[i] + " " : "");}Toast.makeText(MainActivity.this, sb.toString(), 0).show();}});builder.show();
Android入门笔记03相关推荐
- Android入门笔记之更改手机屏幕方向
Android入门笔记之更改手机屏幕方向 <1>简介 通过一个按钮组来改变横屏竖屏显示. <2>关键步骤 主要通过android.app.activity.getRequest ...
- gif透明背景动画_iPad Procreate入门笔记03 - GIF动画制作
更新至Procreate 5 后,新增加了"动画辅助(animation assist)"功能,制作动画更加容易上手且方便了. 下面介绍几种简单的制作方法. 1. GIF最佳画布大 ...
- 使用pil读取gif图有些位置为黑色_iPad Procreate入门笔记03 - GIF动画制作
更新至Procreate 5 后,新增加了"动画辅助(animation assist)"功能,制作动画更加容易上手且方便了. 下面介绍几种简单的制作方法. 1. GIF最佳画布大 ...
- ESP32 入门笔记03:PWM (ESP32 for Arduino IDE)
先导知识 ESP32 入门笔记01:开发板信息.开发环境搭建以及学资料准备 ESP32 入门笔记02: GPIO参考指南 ESP32 有一个 LED PWM 控制器,具有 16 个独立通道,可配置为生 ...
- STM32入门笔记(03):系统时钟控制 RCC (STM32CubeMx 初始化配置)
目的/起源: B站@立邦大侠 的在视频里面提到,他用STM32CubeMx 更清晰地进行STM32系统时钟配置以及时钟架构. STM32 开发流程 : 芯片选型 - 原理图设计 - PCBlayout ...
- Cookie和Session-学习笔记03【Session快速入门、Session细节】
Java后端 学习路线 笔记汇总表[黑马程序员] Cookie和Session-学习笔记01[Cookie_快速入门.Cookie_细节] Cookie和Session-学习笔记02[Cookie案例 ...
- Android Studio 基础入门笔记
Android Studio 基础入门笔记 Android Studio 基础入门笔记 为什么选择使用 Android Studio 而不是EclipseADT 安卓配置JDK AS如何更新 常规的 ...
- Android 插件化原理入门笔记
Android开发笔记 onGithub 笔记,参考7.2中所列参考文章所写,DEMO地址在PluginTestDemoApplication 1.综述 2015年是Android插件化技术突飞猛进的 ...
- Android入门自学笔记
Android入门 前几个月要去作物联网项目,花了一个月入门android本文写于物联网大赛后 Android入门所需书籍 <android第一行代码>-----入门必看书.这本书实例和理 ...
- SpringMVC-学习笔记03【SpringMVC常用注解】
Java后端 学习路线 笔记汇总表[黑马程序员] SpringMVC-学习笔记01[SpringMVC概述及入门案例][day01] SpringMVC-学习笔记02[参数绑定及自定义类型转换] Sp ...
最新文章
- java equal hashcode_Java(二)equal 和 hashcode使用
- springMVC 拦截器
- 你管这破玩意叫 RDB
- ModelSim之命令行仿真入门 (step 2)
- C++ GUI Qt4编程(12)-6.1FindFileDialog
- 阿加莎•克里斯蒂作品04东方快车谋杀案
- 夺命雷公狗---微信开发39----微信语言识别接口1
- 消息队列 应用场景 解析
- C++ 重载赋值运算符
- linux 快速切换ip,linux-如何快速替换IP
- Filebeat 收集日志的那些事儿
- css代码总结,css属性代码大全总结(一)
- java盘点系统_2020年度综合大盘点:火爆IT业的7大Java技术,任何一项都是“卧槽牛逼”!...
- PCB的制作工艺流程
- php ipa下载 解码,ipa下载的方法
- 文档已完成加载后执行document write整个 HTML 页面将被覆盖
- 51单片机内部外设:实时时钟(SPI)
- Android 智能硬件的理解(2018.5.25)
- 关于DBSCAN图像上小圆圈和大圆圈的问题
- 7-4 宿舍谁最高? (20 分) map+结构体的应用