SQLite数据库
说明:这是一个轻量级数据库,嵌入式数据库
数据库的存储数据的意义:当有大量相似结构的数据需要存储的时候,并且具有查询速度快的特点
特点:sqlite数据库底层都是以字符串类型保存,不会区分存入数据库中数据的类型
1.SQLiteOpenHelper抽象类
位置:android.database.sqlite.SQLiteOpenHelper包
功能:一个建立数据库的帮助类
Public Constructors | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
SQLiteOpenHelper(
Context context,
String name,
SQLiteDatabase.CursorFactory factory, int version)
帮助类的构造函数,name:数据库名;factory:游标工厂,通常设置为空;version:数据库版本,必须大于等于1,否则抛出异常,并且降级也会报错
|
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
SQLiteDatabase |
getReadableDatabase()
获得可读的数据库。
不会加线程锁,因为多个线程可同时读一个数据库
| ||||||||||
SQLiteDatabase |
getWritableDatabase()
获取可写的数据库。
会加线程锁,因为多个线程同时写数据到一个数据库可能会出现多线程的问题
| ||||||||||
abstract void |
onCreate(
SQLiteDatabase db)
在第一次创建数据库时调用,通常使用者要建立一个该类的子类,复写这个方法,建立数据库中的表的逻辑通常写在该方法中
| ||||||||||
abstract void |
onUpgrade(
SQLiteDatabase db, int oldVersion, int newVersion)
在数据库需要更新时调用,就是新建立的数据库版本号大于之前的数据库时,通常修改表的结构的逻辑写在该方法中
|
2.SQLiteDatabase终类
位置:android.database.sqlite.SQLiteDatabase包
两种增删改查方法相比较:
(1)sql语句法写整句的sql语句容易出错,并且方法没有返回值
(2)定义好的方法不够灵活,不容易进行多表查询
特殊:(查询数据库中数据通过命令行:sqlite3)
(1)【adb shell】==>【cd data/data/包名/databases】==>【sqlite3 person.db】==>这之后即可输入sql语句操作数据库表了
(2)乱码解决:上边方法会因为你的命令行的解码方式是GBK,Linux用的是utf-8而出现乱码,可通过【chcp 65001】命令改变命令行的解码方式。【chcp 936】是GBK
Constants | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
int | OPEN_READONLY | 只读模式 | |||||||||
int | OPEN_READWRITE | 读写模式 |
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
void |
beginTransaction()
开启事务
| ||||||||||
void |
endTransaction()
关闭事务
| ||||||||||
void |
execSQL(
String sql)
运行一条sql语句,
缺点没有返回值
| ||||||||||
void |
execSQL(
String sql,
Object[] bindArgs)
运行一个条sql语句,
用占位符形式传入参数,缺点没有返回值
| ||||||||||
Cursor |
rawQuery(
String sql,
String[] selectionArgs)
运行一条查询语句,并且返回游标
。查询语句只能用该方法执行,因为它会返回游标对象
| ||||||||||
Cursor |
query(
String table,
String[] columns,
String selection,
String[] selectionArgs,
String groupBy,
String having,
String orderBy)
用该对象封装好的方法查询数据
| ||||||||||
int |
update(
String table,
ContentValues values,
String whereClause,
String[] whereArgs)
用该对象封装好的方法更新数据,
返回值表示影响了多少行数据
| ||||||||||
long |
insert(
String table,
String nullColumnHack,
ContentValues values)
用该对象封装好的方法插入数据,
返回插入的行号,返回值为-1则说明插入失败。nullColumnHack参数值一般为null,组拼字符串用
| ||||||||||
int |
delete(
String table,
String whereClause,
String[] whereArgs)
用该对象封装好的方法删除数据,
返回值表示影响了多少行数据
| ||||||||||
void |
setTransactionSuccessful()
设置一个成功标记,如果这个方法执行则说明事务成功;有异常,则会回滚
| ||||||||||
static SQLiteDatabase |
openDatabase(
String path,
SQLiteDatabase.CursorFactory factory, int flags)
创建一个数据库对象,通过本地数据库文件。参数1:数据库文件地址,
而且必须是data/data目录下,否则无法访问;参数2:null;参数3:数据库只读,可读可写
|
3.ContentValues终类
位置:android.content.ContentValues包
功能:封装数据的对象,底层封装了一个HashMap
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
void |
clear()
清除集合中数据
| ||||||||||
void |
put(
String key,
Byte value)
存储字节值
| ||||||||||
void |
put(
String key,
Integer value)
存储整型值
| ||||||||||
void |
put(
String key,
Float value)
存储单精度浮点值
| ||||||||||
void |
put(
String key,
Short value)
存储短整型值
| ||||||||||
void |
put(
String key, byte[] value)
存储字节数组值
| ||||||||||
void |
put(
String key,
String value)
存储字符串值
| ||||||||||
void |
put(
String key,
Double value)
存储双精度浮点值
| ||||||||||
void |
put(
String key,
Long value)
存储长整值
| ||||||||||
void |
put(
String key,
Boolean value)
存储布尔值
| ||||||||||
void |
putAll(
ContentValues other)
存储全部值
| ||||||||||
void |
putNull(
String key)
存储空值
| ||||||||||
void |
remove(
String key)
删除一个键
| ||||||||||
int |
size()
获取大小
|
ListView控件
1.ListView类
位置:android.widget.ListView包
特点:存放的内容是一个一个的条目
注意:当ListView的高度是包裹内容时,就会做多次检验而调用很多次getView方法,为了确定是否这个高度能把全部条目显示出来
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
void |
setAdapter(
ListAdapter adapter)
设置ListView数据显示需要的数据适配器
| ||||||||||
void |
setOnTouchListener(
View.OnTouchListener l)
设置ListView的触摸事件
| ||||||||||
void |
setOnItemClickListener(
AdapterView.OnItemClickListener listener)
设置条目的点击事件
| ||||||||||
void |
addFooterView(
View v)
添加ListView的脚布局 | ||||||||||
void |
addHeaderView(
View v)
添加ListView的头布局
| ||||||||||
int |
getFooterViewsCount()
获取脚布局显示view的角标索引,索引值会计算headerView
| ||||||||||
int |
getHeaderViewsCount()
获取头布局显示view的角标索引,索引值会计算footerView
| ||||||||||
void |
setSelection(int position)
设置当前ListView选中的条目位置,自定义控件上拉加载滑动到最后时需要调用此方法
| ||||||||||
int |
getCount()
获取ListView条目的数量,包括header和footer |
2.ListAdapter接口
位置:android.widget.ListAdapter包
意义:作为ListView全部填充内容适配器的超类接口
2.1 BaseAdapter抽象类
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
abstract int |
getCount()
复写此方法,返回值为条目的数量
| ||||||||||
abstract Object |
getItem(int position)
通常不用复写此方法,获取指定 位置的条目对象
| ||||||||||
abstract long |
getItemId(int position)
通常不用复写此方法,获取指定位置的条目id
| ||||||||||
abstract View |
getView(int position,
View convertView,
ViewGroup parent)
必须复写的方法,获取制定位置的View对象,
只要一个view显示出来一点点这个方法就会被调用。convertView是历史缓存对象可以做到优化内存的作用,因为当条目过多时会因为你创建的View太多,而销毁的View赶不上创建的速度,造成内存问题--
OutOfMemoryError问题OOM。
convertView表示刚消失在屏幕中的那个View对象,不重新创建而直接复用这个历史缓存对象即对内存的优化
| ||||||||||
void |
notifyDataSetChanged()
刷新ListView中适配器的数据
| ||||||||||
void |
registerDataSetObserver(
DataSetObserver observer)
注册内容观察者
| ||||||||||
void |
unregisterDataSetObserver(
DataSetObserver observer)
解除注册内容观察者
|
2.2 ArrayAdapter<T>类
Public Constructors | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
ArrayAdapter( Context context, int resource, int textViewResourceId, T[] objects)
构造函数,上下文;resource:listview的子条目;textViewResourceId:显示数据的控件id;objects存放数据的数组
| |||||||||||
ArrayAdapter(
Context context, int resource, int textViewResourceId,
List<T> objects)
构造函数,只有objects是存放数据的集合
|
2.3 SimpleAdapter类
Public Constructors | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
SimpleAdapter(
Context context,
List<? extends
Map<
String, ?>> data, int resource,
String[] from, int[] to)
构造方法,上下文;list:存放键值对的集合;resource:listview的子条目item;from:存放键名的数组;int:存放显示数据控件的全部id值的数组
|
3.三种布局填充器的写法
/**
* 方法1:
* 参数:上下文,源布局的id
* ViewGroup:里面可以有自己的孩子,不为空返回的是ViewGroup的父亲,就是布局中的根节点
*/
View view = View.inflate(getApplicationContext(), R.layout.item, null);
/**
* 方法2:通过布局填充器LayoutInflater对象的静态方法填充
*/
view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.item, null);
/**
* 方法3:通过服务获取填充器,然后调用填充器中的填充方法
*/
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.item, null);
4.常见ListView写法
private class MyAdapter extends BaseAdapter {
private ViewHolder holder;
private BitmapUtils utils;
@Override
public int getCount() {
return list.size();
}
@Override
public News getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = View.inflate(context, R.layout.item_news_listview, null);
holder = new ViewHolder();
holder.iv_img = (ImageView) convertView.findViewById(R.id.iv_img);
holder.tv_title = (TextView) convertView.findViewById(R.id.tv_title);
holder.tv_pub_date = (TextView) convertView.findViewById(R.id.tv_pub_date);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
utils = new BitmapUtils(context);
utils.display(holder.iv_img, list.get(position).listimage);
holder.tv_title.setText(list.get(position).title);
holder.tv_pub_date.setText(list.get(position).pubdate);
// 对已经读过的条目标题进行标红处理
if (list.get(position).isRead) {
holder.tv_title.setTextColor(Color.GRAY);
} else {
holder.tv_title.setTextColor(Color.BLACK);
}
return convertView;
}
}
static class ViewHolder {
public ImageView iv_img;
public TextView tv_title;
public TextView tv_pub_date;
}
网络编程
知识点:
(1)Android中主线程不能进行耗时的操作,(如网络连接、拷贝大数据等)会抛出anr异常——Application not response异常,应用无响应。解决方法:在子线程中进行这些操作
(2)在4.0系统后,当你在主线程中只要访问网络就会抛出NetWorkOnMainThreadException
(3)在4.0系统后,规定了只有主线程才能更新UI,其他线程对UI控件进行操作会抛出ViewRootImpl$CalledFromWrongThreadException
(4)android系统底层有一个审计机制,这个机制禁止其他线程更新UI,这个机制在应用界面完全可见时才会开启,就是在OnStrart方法之后运行的更新操作会被禁止。如果你更新的操作在这个机制启动时间之前,则能更新UI
(5)与进度相关的UI都可以在子线程中更新UI
1.HttpURLConnection抽象类
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
String |
getRequestMethod()
设置请求的方式get或者post
| ||||||||||
int |
getResponseCode()
获得相应的状态码
| ||||||||||
void |
setConnectTimeout(int timeoutMillis)
设置连接的超时时间
| ||||||||||
InputStream |
getInputStream()
获取Socket的输入流
| ||||||||||
OutputStream |
getOutputStream()
获取Socket的输出流
| ||||||||||
void |
setRequestProperty(
String field,
String newValue)
设置一个请求头
| ||||||||||
void |
setDoOutput(boolean newValue)
设置可以向服务器写数据
| ||||||||||
void |
setReadTimeout(int timeoutMillis)
设置读取的超时时间,当连结完毕可是服务器不吐资源时设置
|
2.消息传递机制
原理:解决子线程更新UI的问题。把子线程中获取的数据封装到Message对象中的obj中或者Bundle中,通过Handler对象把数据发送回主线程的复写的HandeMessage()方法中,然后更新UI即可。
传送的过程:Message对象被传到Handler对象中的消息队列中,这里有一个Looper的监听器会监听这个消息队列,只要检测到有信息存入就会把信息发送到HanleMessage()方法中
2.1 Message终类
位置:android.os.Message包
Public Constructors | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Message()
通过构造函数建立Message对象,一般不用构造函数创建Message对象,会浪费资源
|
Fields | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
public Object | obj | 消息对象中存储转送数据的字段 | |||||||||
public int | what | 标示消息对象的标识 |
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Bundle |
getData()
获取存储在消息对象中Bundle对象
| ||||||||||
static Message |
obtain()
获取或者创建消息对象,会判断消息池是否为空,空则从新创建对象,不为空则从池子中取消息对象
| ||||||||||
void |
setData(
Bundle data)
设置Bundle型的数据存入Message对象中,可存放多条数据
| ||||||||||
void |
sendToTarget()
等同于target.sendMessage(this),target在Handler调用obtainMessage()时被赋值了,就是前面的Handler
|
2.2 Handler
位置:android.os.Handler包
Public Constructors | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Handler()
默认的构造函数
|
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
void |
handleMessage(
Message msg)
一般复写该方法获取消息对象传递的数据
| ||||||||||
final boolean |
postDelayed(
Runnable r, long delayMillis)
计时器,这个Runnable是主线程运行的方法,
delayMillis是定时的间断
| ||||||||||
final boolean |
sendEmptyMessage(int what)
发送一个带标识的空信息,在handleMessage方法中判断标识数字来进行逻辑书写
| ||||||||||
final Message |
obtainMessage()
等同于Message.obtain(this)方法
| ||||||||||
final void |
removeCallbacksAndMessages(
Object token)
移除handler中维护的全部任务,参数传入null即可
|
3.更新UI的特殊方法
3.1 Activity类
位置:android.app.Activity包
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
final void |
runOnUiThread(
Runnable action)
该方法中的任何更新的逻辑都会在UI线程中执行,无论这个方法是否在子线程中
|
4.SmartImageView开源项目
描述:这是一个开源框架,定义了解析图片的url地址,更新UI的功能【setImageUrl(String url)】
原理:就是定义一个类SmartImageView继承ImageView,然后内部定义解析url地址获取Bitmap对象的方法,然后再调用setImageBitmap方法设置控件的图片数据
5.HttpClient接口
位置:org.apache.http.client.HttpClient包
功能:能够运行Http请求,处理cookie。作为第二种实现登录注册的方法
缺点:更新UI仍需要用消息传递机制或者runOnMainThread()这种方法才能实现,没有把这一整体操作全部封装好
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
abstract HttpResponse |
execute(
HttpUriRequest request)
通过注册请求获取Http响应对象
|
5.1 DefaultHttpClient类
作用:一般new对象都是new的这个类的对象
5.2 HttpGet类
描述:是HttpUriRequest的实现类,get方式的http的请求对象。一般通过其构造函数初始化这个对象
5.3 HttpResponse接口
描述:响应对象,可以通过此对象获取http响应中的数据
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
abstract HttpEntity |
getEntity()
获取存放响应正文数据的实体,通过实体对象的getContent()方法可以获取响应正文的输入流
| ||||||||||
abstract StatusLine |
getStatusLine()
获取响应的状态行对象,状态行中包含状态码,通过getStatusCode()方法
|
5.4 HttpPost类
描述:HttpuriRequest的实现类,post请求方式的http对象,此对象定义了封装数据实体
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
void |
setEntity(
HttpEntity entity)
添加实体的方法,封装post请求的数据
|
5.5 UrlEncodedFormEntity类
描述:HttpEntity接口的实现类,可以封装Ur表单l类型的数据的实体
Public Constructors | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
UrlEncodedFormEntity(
List<? extends
NameValuePair> parameters)
通过键值对对象对这个实体进行初始化,编码为默认编码
|
5.6 BasicNameValuePair类
描述:NameValuePair接口的实现类,可以封装键值对形式的表单数据
Public Constructors | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
BasicNameValuePair(
String name,
String value)
一般通过此构造函数封装键值对即可
|
6.AsyncHttpClient开源项目
(1)Get方式发送请求
// 建立框架的主要客户端对象
AsyncHttpClient client = new AsyncHttpClient();
// 调用get方法来想服务端发送get请求
client.get(path, new AsyncHttpResponseHandler() {
// 请求成功时调用
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
try {// 获取服务端返回的数据
Toast.makeText(getApplicationContext(), new String(responseBody, "gbk"), 1).show();
} catch (Exception e) {
e.printStackTrace();
}
}
// 请求失败时调用
@Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
System.out.println("请求失败!");
}
});
(2)Post方法发送请求
AsyncHttpClient client = new AsyncHttpClient();
// 向Asyn客户端对象中填充参数对象
RequestParams params = new RequestParams();
params.put("username", username);
params.put("password", password);
// 发送Post请求
client.post(path, params, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
try {
Toast.makeText(getApplicationContext(), new String(responseBody, "gbk"), 0).show();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
System.err.println("请求失败!");
}
});