网络编程4"/>
Android开发——SQLite数据库、ListView、网络编程4
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;@Overridepublic int getCount() {return list.size();}@Overridepublic News getItem(int position) {return list.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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的请求对象。一般通过其构造函数初始化这个对象
Public Constructors | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
HttpGet( String uri) 通过制定uri路径建立请求对象 |
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() {// 请求成功时调用@Overridepublic void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {try {// 获取服务端返回的数据Toast.makeText(getApplicationContext(), new String(responseBody, "gbk"), 1).show();} catch (Exception e) {e.printStackTrace();}}// 请求失败时调用@Overridepublic 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() {@Overridepublic void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {try {Toast.makeText(getApplicationContext(), new String(responseBody, "gbk"), 0).show();} catch (Exception e) {e.printStackTrace();}}@Overridepublic void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {System.err.println("请求失败!");}});
更多推荐
Android开发——SQLite数据库、ListView、网络编程4
发布评论