Android开发——SQLite数据库、ListView、网络编程4

来源:互联网 发布:男生礼物 知乎 编辑:程序博客网 时间:2024/06/08 01:04

SQLite数据库

说明:这是一个轻量级数据库,嵌入式数据库

数据库的存储数据的意义:当有大量相似结构的数据需要存储的时候,并且具有查询速度快的特点

特点:sqlite数据库底层都是以字符串类型保存,不会区分存入数据库中数据的类型

1.SQLiteOpenHelper抽象类

位置:android.database.sqlite.SQLiteOpenHelper包

功能:一个建立数据库的帮助类

Public ConstructorsSQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)

帮助类的构造函数,name:数据库名;factory:游标工厂,通常设置为空;version:数据库版本,必须大于等于1,否则抛出异常,并且降级也会报错
Public MethodsSQLiteDatabasegetReadableDatabase()
获得可读的数据库。不会加线程锁,因为多个线程可同时读一个数据库
SQLiteDatabasegetWritableDatabase()
获取可写的数据库。会加线程锁,因为多个线程同时写数据到一个数据库可能会出现多线程的问题
abstract voidonCreate(SQLiteDatabase db)
在第一次创建数据库时调用,通常使用者要建立一个该类的子类,复写这个方法,建立数据库中的表的逻辑通常写在该方法中
abstract voidonUpgrade(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

ConstantsintOPEN_READONLY只读模式intOPEN_READWRITE读写模式

Public MethodsvoidbeginTransaction()
开启事务
voidendTransaction()
关闭事务
voidexecSQL(String sql)
运行一条sql语句,缺点没有返回值
voidexecSQL(String sql, Object[] bindArgs)
运行一个条sql语句,用占位符形式传入参数,缺点没有返回值
CursorrawQuery(String sql, String[] selectionArgs)
运行一条查询语句,并且返回游标。查询语句只能用该方法执行,因为它会返回游标对象
Cursorquery(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
用该对象封装好的方法查询数据
intupdate(String table, ContentValues values, String whereClause, String[] whereArgs)
用该对象封装好的方法更新数据,返回值表示影响了多少行数据
longinsert(String table, String nullColumnHack, ContentValues values)
用该对象封装好的方法插入数据,返回插入的行号,返回值为-1则说明插入失败。nullColumnHack参数值一般为null,组拼字符串用
intdelete(String table, String whereClause, String[] whereArgs)
用该对象封装好的方法删除数据,返回值表示影响了多少行数据
voidsetTransactionSuccessful()
设置一个成功标记,如果这个方法执行则说明事务成功;有异常,则会回滚
static SQLiteDatabaseopenDatabase(String path, SQLiteDatabase.CursorFactory factory, int flags)
创建一个数据库对象,通过本地数据库文件。参数1:数据库文件地址,而且必须是data/data目录下,否则无法访问;参数2:null;参数3:数据库只读,可读可写

3.ContentValues终类

位置:android.content.ContentValues包

功能:封装数据的对象,底层封装了一个HashMap

Public Methodsvoidclear()
清除集合中数据
voidput(String key, Byte value)
存储字节值
voidput(String key, Integer value)
存储整型值
voidput(String key, Float value)
存储单精度浮点值
voidput(String key, Short value)
存储短整型值
voidput(String key, byte[] value)
存储字节数组值
voidput(String key, String value)
存储字符串值
voidput(String key, Double value)
存储双精度浮点值
voidput(String key, Long value)
存储长整值
voidput(String key, Boolean value)
存储布尔值
voidputAll(ContentValues other)
存储全部值
voidputNull(String key)
存储空值
voidremove(String key)
删除一个键
intsize()
获取大小

ListView控件

1.ListView类

位置:android.widget.ListView包

特点:存放的内容是一个一个的条目

注意:当ListView的高度是包裹内容时,就会做多次检验而调用很多次getView方法,为了确定是否这个高度能把全部条目显示出来

Public MethodsvoidsetAdapter(ListAdapter adapter)
设置ListView数据显示需要的数据适配器
voidsetOnTouchListener(View.OnTouchListener l)
设置ListView的触摸事件
voidsetOnItemClickListener(AdapterView.OnItemClickListener listener)
设置条目的点击事件
voidaddFooterView(View v)
    添加ListView的脚布局
voidaddHeaderView(View v)
添加ListView的头布局
intgetFooterViewsCount()
获取脚布局显示view的角标索引,索引值会计算headerView
intgetHeaderViewsCount()
获取头布局显示view的角标索引,索引值会计算footerView
voidsetSelection(int position)
设置当前ListView选中的条目位置,自定义控件上拉加载滑动到最后时需要调用此方法
intgetCount()
     获取ListView条目的数量,包括header和footer

2.ListAdapter接口

位置:android.widget.ListAdapter包

意义:作为ListView全部填充内容适配器的超类接口

2.1 BaseAdapter抽象类

Public Methodsabstract intgetCount()
复写此方法,返回值为条目的数量
abstract ObjectgetItem(int position)
通常不用复写此方法,获取指定 位置的条目对象
abstract longgetItemId(int position)
通常不用复写此方法,获取指定位置的条目id
abstract ViewgetView(int position, View convertView, ViewGroup parent)
必须复写的方法,获取制定位置的View对象,只要一个view显示出来一点点这个方法就会被调用。convertView是历史缓存对象可以做到优化内存的作用,因为当条目过多时会因为你创建的View太多,而销毁的View赶不上创建的速度,造成内存问题--OutOfMemoryError问题OOMconvertView表示刚消失在屏幕中的那个View对象,不重新创建而直接复用这个历史缓存对象即对内存的优化
voidnotifyDataSetChanged()
刷新ListView中适配器的数据
voidregisterDataSetObserver(DataSetObserver observer)
注册内容观察者
voidunregisterDataSetObserver(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 ConstructorsSimpleAdapter(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 MethodsStringgetRequestMethod()
设置请求的方式get或者post
intgetResponseCode()
获得相应的状态码
voidsetConnectTimeout(int timeoutMillis)
设置连接的超时时间
InputStreamgetInputStream()
获取Socket的输入流
OutputStreamgetOutputStream()
获取Socket的输出流
voidsetRequestProperty(String field, String newValue)
设置一个请求头
voidsetDoOutput(boolean newValue)
设置可以向服务器写数据
voidsetReadTimeout(int timeoutMillis)
设置读取的超时时间,当连结完毕可是服务器不吐资源时设置

2.消息传递机制

原理:解决子线程更新UI的问题。把子线程中获取的数据封装到Message对象中的obj中或者Bundle中,通过Handler对象把数据发送回主线程的复写的HandeMessage()方法中,然后更新UI即可。

传送的过程:Message对象被传到Handler对象中的消息队列中,这里有一个Looper的监听器会监听这个消息队列,只要检测到有信息存入就会把信息发送到HanleMessage()方法中

2.1 Message终类

位置:android.os.Message包

Public ConstructorsMessage()
通过构造函数建立Message对象,一般不用构造函数创建Message对象,会浪费资源
Fieldspublic Objectobj消息对象中存储转送数据的字段public intwhat标示消息对象的标识Public MethodsBundlegetData()
获取存储在消息对象中Bundle对象
static Messageobtain()
获取或者创建消息对象,会判断消息池是否为空,空则从新创建对象,不为空则从池子中取消息对象
voidsetData(Bundle data)
设置Bundle型的数据存入Message对象中,可存放多条数据
voidsendToTarget()
等同于target.sendMessage(this),target在Handler调用obtainMessage()时被赋值了,就是前面的Handler

2.2 Handler

位置:android.os.Handler包

Public ConstructorsHandler()
默认的构造函数
Public MethodsvoidhandleMessage(Message msg)
一般复写该方法获取消息对象传递的数据
final booleanpostDelayed(Runnable r, long delayMillis)
计时器,这个Runnable是主线程运行的方法,delayMillis是定时的间断
final booleansendEmptyMessage(int what)
发送一个带标识的空信息,在handleMessage方法中判断标识数字来进行逻辑书写
final MessageobtainMessage()
等同于Message.obtain(this)方法
final voidremoveCallbacksAndMessages(Object token)
移除handler中维护的全部任务,参数传入null即可

3.更新UI的特殊方法

3.1 Activity类

位置:android.app.Activity包

Public Methodsfinal voidrunOnUiThread(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 Methodsabstract HttpResponseexecute(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 Methodsabstract HttpEntitygetEntity()
获取存放响应正文数据的实体,通过实体对象的getContent()方法可以获取响应正文的输入流
abstract StatusLinegetStatusLine()
获取响应的状态行对象,状态行中包含状态码,通过getStatusCode()方法

5.4 HttpPost类

描述:HttpuriRequest的实现类,post请求方式的http对象,此对象定义了封装数据实体

Public MethodsvoidsetEntity(HttpEntity entity)
添加实体的方法,封装post请求的数据

5.5 UrlEncodedFormEntity类

描述:HttpEntity接口的实现类,可以封装Ur表单l类型的数据的实体

Public ConstructorsUrlEncodedFormEntity(List<? extends NameValuePair> parameters)
通过键值对对象对这个实体进行初始化,编码为默认编码

5.6 BasicNameValuePair类

描述:NameValuePair接口的实现类,可以封装键值对形式的表单数据

Public ConstructorsBasicNameValuePair(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("请求失败!");}});


0 0
原创粉丝点击