Android课堂笔记(四)——调试、SQLite

目录

一. Android 调试

1.Android 调试的主要组件

2.生成、检查日志

3.从带有 ADT插件 的 Eclipse 中调试应用

3.1 Debug透视图

3.2 DDMS透视图

3.3 ADB 安卓调试桥

二.SQLite

1.数据存储机制

2.SQLite数据库

3.使用 SQLite 的两种方式

4.使用 ADB工具shell 操纵SQLite

5.通过 Java代码 操纵SQLite

6.登录注册交互实例

7.SQLite 小结


一. Android 调试

1.Android 调试的主要组件

  • Android 调试桥 (ADB)
  • Dalvik 调试监视服务 (DDMS)
  • 设备 / AVD
  • JDWP 调试器
  • 除了主调试工具,还可以使用以下工具来调试和配置应用:
  1. Hierarchy Viewer
  2. Traceview

2.生成、检查日志

  • Android 提供 LogCat类 监视应用程序的日志输出,通过 ADB / DDMS 读取实时消息
  • 日志内容:
  1. 仿真器引发错误时的堆栈跟踪
  2. 通过使用 android.util 包的 Log类方法 从应用程序打印消息
  3. Android系统生成的消息
  • 日志严重性级别按 降序 排列依次为:
  1. 错误 error :Log.e(String tag, String msg)
  2. 警告 wanring :Log.w()
  3. 信息性消息 info :Log.i()
  4. 调试消息 debug :Log.d()
  5. 详细信息 verbose::Log.v()

3.从带有 ADT插件 的 Eclipse 中调试应用

3.1 Debug透视图

  • 提供 进入或跨过 方法调用 和 窥视变量以检查其值的功能

3.2 DDMS透视图

  • 提供用于为调试选择各个过程的工具

3.3 ADB 安卓调试桥

  • Android Debug Bridge:充当开发硬件 和 设备/仿真器 之间的通信媒介
  • 一般最多允许同时存在 16个 运行虚拟机,指定 des 确定连接哪个虚拟机运行
  •  ADB命令用法:adb [-d|-e|-s <serial number>] <command>
  • -d:指示命令到已连接的 USB 设备
  • -e:指示命令到正在运行的设备
  • -s<serial number>:指示命令到具有给定序列号的 USB 设备或仿真器
  • 常见ADB命令:

命令

描述

devices

生成已连接的仿真器/设备列表。

序列号 + 状态(脱机/设备)

get-serialno

打印已连接的设备序列号字符串。

get-state

打印仿真器/设备实例的 ADB 状态。

install <path-to-apk>

在仿真器/设备上安装 Android 应用程序(指定为到 .apk 文件的完整路径)。

kill-server

终止 ADB 服务器进程。

logcat [<option>] [<filter-specs>]

将日志数据打印到屏幕。

 

pull <remote> <local>

将指定文件从仿真器/设备实例复制到您的计算机。 

push <local> <remote>

将指定文件从您的计算机复制到仿真器/设备实例。

 

Shell or shell [<shellCommand>]

 

在目标仿真器/备实例中启动远程 shell,或在目标仿真器/设备中发出 shell 命令。

 Example:adb [-d|-e|-s {<serialNumber>}] shell

start-server

检查 ADB 服务器进程是否正在运行,如果没有运行,启动该服务器进程。

ADB shell 可以执行的命令:

Shell 命令

描述

dumpsys

将系统数据转储到屏幕。

dumpstate

将状态转储到文件。

logcat [<option>]... [<filter-spec>]...

启用无线日志记录并将输出打印到屏幕。

dmesg

将内核调试消息打印到屏幕。

start

启动(重新启动)仿真器/设备实例。

stop

停止执行仿真器/设备实例。

二.SQLite

1.数据存储机制

  • SQLite 数据库 (SQLite Database):存储大量数据,需要关系型数据库来管理数据
  • 内部存储器 (Internal Storage):数据量小,且很少更改,文件属于应用私有
  • 外部存储器 (External Storage):对内部存储器的扩充,存入的文件可以被所有应用访问
  • 共享首选项 (Shared Preferences):存储原生数据类型的键值对,是快速存储默认值、用户偏好设置的理想方法
  • 网络连接 (Internet Connection):使用能够访问远程位置的数据

2.SQLite数据库

  • 自给自足的、无服务器的、零配置的、事务性的、开源的、轻量级的SQL数据库引擎
  • 目的:2000年,D.Richard.Hipp为了 不需要管理即可操作程序 而设计了SQLite
  • SQLite数据库 特点:
  1. 自足自给的:不需要任何外部依赖
  2. 无服务器的:不需要单独的服务器或操作系统
  3. 零配置的:不需要安装或管理
  4. 事务性的:完全兼容ACID,允许从多个进程安全访问
  5. 轻量级的:完全配置时小于400KB,省略可选功能配置小于250KB
  • SQLite数据库 数据类型:

3.使用 SQLite 的两种方式

  • SQLite数据库 存储位置: /data/data/<package_name>/databases 文件夹
  • 默认情况下,所有数据库私有,仅供创建它们的应用访问
  • 创建 SQLite数据库时,应考虑因素:
  1. 图像、音频文件不应存储在数据库中
  2. 所有表应包括一个自动递增的键字段,即唯一索引值
  • 创建数据库,有两种方式:
  1. 使用 SQLite工具,Linux shell (复杂 用得少)
  2. 通过 Java代码 编程

4.使用 ADB工具shell 操纵SQLite

  • ADB工具:
  • 在执行ADB shell命令之前,必须开启AVD(虚拟机),否则会报错 not found

 

  • shell 命令总结:
  1. adb shell:进入adb shell
  2. mkdir /data/data/com.Lyrelion.log/databases :创建数据库目录结构
  3. cd /data/data/com.Lyrelion.log/databases :进入数据库目录结构
  4. sqlite3 ww :创建数据ww
  5. .databases :查看所有数据库
  6. create table t_user (id integer primary key ,name text,pwd name):创建表t_user  
  7. .tables:查看所有表
  8. insert into t_user values (1,“andy”,“123456”):插入信息
  9. select * from t_user:查看信息 
  10. exit:退出

5.通过 Java代码 操纵SQLite

5.1 创建SQLite 相关类

  • SQLiteDatabase类:公开方法实现数据库增删改查,如:insert(),update(),delete(),query(),execSQL()
  • SQLiteOpenHelper类:用于创建和管理数据库,包括数据库版本管理
  • Cursor接口:查询返回的结果集
  • ContentValues类:一个该类对象表示一行数据
  • SQLiteQueryBuilder类:提供方法从SQLite数据库中检索数据
  • SQLiteStatement类:实现预编译功能

5.2 SQLiteDatabase 类

  • 创建和删除数据库、对数据库执行 SQL命令及其他数据库管理方法,提供以下方法:
  • close():关闭数据库
  • execSQL(String sql):一个此方法仅能输入一条sql语句,一旦创建了数据库,可执行此方法在数据库中创建表
  • getPath() / getVersion():获取路径 / 版本号
  • isOpen() / isReadOnly() :判断是否打开 / 是否只读

5.3 SQLiteOpenHelper 类

  • 创建数据库的首选方法,此类是抽象类,用于创建、打开和升级数据库,有以下回调方法:
  • onCreate(SQLiteDatabase db):方法比较鸡肋,创建数据库的同时才能创建表,创建过数据库再建表会失败
  • onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion):更改数据库旧版本至新版本
  • onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion)
  • onOpen(SQLiteDatabase db):打开数据库
  • SQLiteOpenHelper 类提供的其他一些方法有:close()    getWritableDatabase()    getReadableDatabase()

5.4 Cursor接口

  • 返回结果集,提供以下方法:

method 

description

args

moveToPosition(int position)

将光标移动到结果集中的指定行

position:指定移动的位置

moveToFirst()

将光标移动到结果集中的第一行

 

moveToNext()

将光标移动到结果集中的下一行

 

moveToLast()

将光标移动到结果集中的最后行

 

moveToPrevious()

将光标移动到结果集中的前一行

 

getCount()

返回结果集存在的行数

 

getColumnIndex(String columnName)

返回给定列名的基于零的索引或-1(指定列不存在)

columnName:指定目标列的名称

getColumnIndexOrThrow()

返回给定列名的索引(指定列不存在引发异常)

 

getColumnName(int columnIndex)

返回给定列索引的名称

columnIndex:指定目标列的索引

getColumnNames()

返回字符串数组,由结果集中的所有列的名称组成

 

5.5 SQLiteStatement类

  • 实现预编译功能,提供以下方法:
  • execute()    
  • executeInsert()    
  • executeUpdateDelete()

5.6 SQLiteQueryBuilder类

  • 检索数据,提供以下方法:      
  • setTables(String tables)    
  • appendWhere(CharSeqyence inWhere)    
  • query(SQLiteDatabase db,String[] columns,String selections,String[] selectionArgs,String groupBy,String having,String sortOdert)

6.登录注册交互实例

  • 书写 登录 activity_main.xml、注册 activity_register.xml、成功登录 activity_success.xml 的布局页面
  • 创建 数据库及表 相关文件:MyDBOpenHelper.java
  • 书写 登录 MainActivity.java、注册 RegisterActivity.java、登陆成功 SuccessActivity.java 的活动界面
  • 登录活动界面逻辑:声明并创建数据库对象  获取布局组件对象 设置登录按钮点击监听事件(判断是否输入:未输入就提示,输入就执行数据库查询操作 判断库中是否有对应数据,若有则登录成功,若没有则跳转注册界面) 书写数据库查询的方法
  • ⑤注册活动页面逻辑:声明并创建数据库对象  获取布局组件对象 设置提交按钮点击监听事件(判断是否输入:未输入就提示,输入就执行数据库插入操作 然后跳转到登录界面) 书写数据库插入的方法
  • 布局文件代码展示: 
<!-- activity_main.xml 登录布局界面 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    ...
    android:orientation="vertical" // 线性垂直布局
    tools:context=".MainActivity" > // 登录布局页面 和 登录活动界面关联
    <EditText
        android:id="@+id/admin"
        android:drawableLeft="@drawable/admin" // 插入图标
        android:hint="请输入用户名:" // 文本提示信息    />
    <EditText
        android:id="@+id/password"     ...    />  
    <Button
        android:id="@+id/login"     ...
        android:layout_gravity="center" // 按钮居中对齐
        android:layout_marginTop="30dp" // 调整按钮外边距
        android:text="Login"/>
</LinearLayout>

<!-- activity_register.xml 注册布局界面 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:orientation="vertical" // 线性垂直布局
    tools:context=".RegisterActivity" > // 注册布局界面 和 注册活动界面关联
   <EditText
        android:id="@+id/admin"
        android:drawableLeft="@drawable/admin" 
        android:hint="请输入用户名:" />
   <EditText
        android:id="@+id/password"    .../>    
   <Button
        android:id="@+id/register"    .../>
</LinearLayout>

<!-- activity_success.xml 登录成功布局界面 -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" // 相对布局
    ...
    tools:context=".SuccessActivity" > // 登录成功布局界面 和 登录成功活动界面关联
    <TextView    ...
        android:text="恭喜你登录成功!" />
</RelativeLayout>
  • 创建数据库及表 MyDBOpenHelper.java 代码展示:
public class MyDBOpenHelper extends SQLiteOpenHelper {
	//1:创建数据库的 SQL命令,被存储在变量 CREATE_TABLE_SQL中,下面调用此变量
	final String CREATE_TABLE_SQL="create table t_admin (id integer primary key,name text,password text);";
	public MyDBOpenHelper(Context context, String name, CursorFactory factory,
			int version) {
		super(context, name, null, version); // 第三个参数 factory不存在,要赋值null,然后打印日志
		Log.w("SQLite", "构造函数 MyDBOpenHelper()初始化");
	}
	@Override
	// 下面的方法比较鸡肋 只有在创建数据库的同时才能创建表 创建过数据库再创建表会失败
	public void onCreate(SQLiteDatabase db) { // 首次创建数据库时调用 onCreate()
		//2:创建数据库表 db.execSQL(数据库语句 仅能写一条 这里写了变量名 在上面定义具体语句)
		db.execSQL(CREATE_TABLE_SQL);
		Log.w("SQLite", "onCreate()方法创建数据库t_admin");
	}
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		Log.w("SQLite", "onUpgrade()方法更改数据库旧版本"+oldVersion+"至新版本"+newVersion);
	}
	@Override
	public void onOpen(SQLiteDatabase db) {
		Log.w("SQLite", "onOpen()方法打开了数据库"+db.getVersion());
		super.onOpen(db);
	}}
  • 登录活动界面  MainActivity.java 代码展示:
public class MainActivity extends Activity {
	private MyDBOpenHelper myDbOpenhelper; // 声明  MyDBOpenHelper 对象
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 创建  MyDBOpenHelper对象 创建数据库名admin 内容为空 版本号是1
        myDbOpenhelper = new MyDBOpenHelper(MainActivity.this, "admin", null, 1);
        // 1:获取组件对象 对象名见名知意
         final EditText adminEditText = (EditText) findViewById(R.id.admin);
         final EditText passwordEditText = (EditText) findViewById(R.id.password);
         final Button loginButton = (Button) findViewById(R.id.login);
         // 2:设置 button按钮点击事件监听 先写最终的分号保证代码正确性
         loginButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// 2.1:获取用户输入的信息 此处会提示将上面的 adminEditText 改成 final类型
                // 强制转化成 String数据类型原因:下面方法用 String类型 否则报错
				String name = adminEditText.getText().toString();
				String password = passwordEditText.getText().toString();
				// 3:判断用户是否输入账号密码
				if ("".equals(name)&&"".equals(password)) {
					// 如果没有输入账号密码 弹出对话框提示 记得别忘记show()
					Toast.makeText(MainActivity.this, "用户名或密码不能为空", Toast.LENGTH_SHORT).show();
				}else{ // 如果输入了账号密码 调用查询方法
				if(selectData(myDbOpenhelper.getReadableDatabase(),name,password)) {
						// 查询到账号密码了 则跳转显示成功登录界面
						Intent intent = new Intent(MainActivity.this,SuccessActivity.class);
						startActivity(intent);
					}else { // 未查询到账号密码 则跳转到注册界面
						Intent intent = new Intent(MainActivity.this, RegisterActivity.class);
						startActivity(intent);
					}}}});}
    // 查询需要的对象 这是自定义查询方法 上面会调用这个方法 如查询名字 密码
    public Boolean selectData(SQLiteDatabase db,String name,String password){   	
    	Boolean mark = false; // 没查询到结果,返回false
    	// Cursor接口 返回数据结果集
    	Cursor cursor = db.query("t_admin", null, "name=?and password=?", new String[]{name,password}, null, null, null);
    	if (cursor.moveToNext()) { // 查询到结果 并打印日志
			Log.w("SQLite","用户名:"+ cursor.getString(1));
			Log.w("SQLite","密码:"+cursor.getString(2));
			mark = true;
		}
    	return mark;    	
    }}
  • 注册活动界面 RegisterActivity.java 代码展示:
public class RegisterActivity extends Activity {
		private MyDBOpenHelper dbOpenHelper ; // 定义 MyDBOpenHelper对象
	    @Override
	    protected void onCreate(Bundle savedInstanceState) {
	        super.onCreate(savedInstanceState);
	        setContentView(R.layout.activity_register);
	        dbOpenHelper = new MyDBOpenHelper(RegisterActivity.this, "admin", null, 1);
	        final EditText adminEdit = (EditText) findViewById(R.id.admin);
	        final EditText passwordEdit = (EditText) findViewById(R.id.password);
	        final Button registerButton = (Button) findViewById(R.id.register);
	        registerButton.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					// 获取用户输入的信息
					String name = adminEdit.getText().toString();
					String password = passwordEdit.getText().toString();
					// 判断用户是否输入了账号密码
					if ("".equals(name)||"".equals(password)) {
						Toast.makeText(RegisterActivity.this, "用户名或密码不能为空!", Toast.LENGTH_SHORT).show();
					}else { // 若用户输入了账户密码 执行 insertData()方法插入数据		
						insertData(dbOpenHelper.getReadableDatabase(), name, password);
					    Intent intent = new Intent(RegisterActivity.this, MainActivity.class);	
					    startActivity(intent);
					}}});}
	    // 创建insertData()方法 实现插入数据
	    public void insertData(SQLiteDatabase database,String  name,String password){
	    	ContentValues values = new ContentValues(); // 一个 ContentValues类 表示一行数据
	    	values.put("name", name); // values.put:放入键值对
	    	values.put("password", password);
	    	database.insert("t_admin", null, values); // 将上述数据执行插入
	    }}
  • 运行后日志打印展示:

7.SQLite 小结

  • SQLite 是一个 RDBMS,ADB允许用户直接从 shell命令行 或 Java脚本 操纵数据库
  • Android 提供各种方法 存储检索应用数据,即:SQLite、内部存储器、外部存储器、共享首选项和网络连接
  • SQLiteDatabase类公开用于管理 SQLite 数据库的各种方法
  • SQLiteDatabase类提供 openOrCreateDatabase() 方法来打开现有数据库或创建新数据库(如果不存在)
  • SQLiteOpenHelper类是抽象类,用于创建、打开和升级数据库,并管理数据库版本
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lyrelion

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值