Android 各大网络请求库的比较及实战

Android 各大网络请求库的比较及实战
Android 各大网络请求库的比较及实战

Android 各大网络请求库的比较及实战HttpUrlConnection

最开始学android的时候用的网络请求是HttpUrlConnection,当时很多东西还不知道,但是在android 2.2及以下版本中HttpUrlConnection存在着一些bug,所以建议在android 2.3以后使用HttpUrlConnection,之前使用HttpClient。

在Android 2.2版本之前,HttpClient拥有较少的bug,因此使用它是最好的选择。而在Android 2.3版本及以后,HttpURLConnection则是最佳的选择。它的API简单,体积较小,因而非常适用于Android项目。压缩和缓存机制可以有效地减少网络访问的流量,在提升速度和省电方面也起到了较大的作用。对于新的应用程序应该更加偏向于使用HttpURLConnection,因为在以后的工作当中我们也会将更多的时间放在优化HttpURLConnection上面。

特点

比较轻便,灵活,易于扩展

在3.0后以及4.0中都进行了改善,如对HTTPS的支持

在4.0中,还增加了对缓存的支持

用法

GET

[java] view plain copy 在CODE上查看代码片派生到我的代码片

public String get(String urlPath) {

HttpURLConnection connection = null;

InputStream is = null;

try {

URL url = new URL(urlPath);

//获得URL对象

connection = (HttpURLConnection) url.openConnection();

//获得HttpURLConnection对象

connection.setRequestMethod("GET");

// 默认为GET

connection.setUseCaches(false);

//不使用缓存

connection.setConnectTimeout(10000);

//设置超时时间

connection.setReadTimeout(10000);

//设置读取超时时间

connection.setDoInput(true);

//设置是否从httpUrlConnection读入,默认情况下是true;

if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {

//相应码是否为200

is = connection.getInputStream();

//获得输入流

BufferedReader reader = new BufferedReader(new InputStreamReader(is));

//包装字节流为字符流

StringBuilder response = new StringBuilder();

String line;

while ((line = reader.readLine()) != null) {

response.append(line);

}

return response.toString();

}

} catch (Exception e) {

e.printStackTrace();

} finally {

if (connection != null) {

connection.disconnect();

connection = null;

}

if (is != null) {

try {

is.close();

is = null;

} catch (IOException e) {

e.printStackTrace();

}

}

}

return null;

}

POST

[java] view plain copy 在CODE上查看代码片派生到我的代码片private String post(String urlPath, Map params) { if (params == null || params.size() == 0) {

return get(urlPath);

}

OutputStream os = null;

InputStream is = null;

HttpURLConnection connection = null;

StringBuffer body = getParamString(params);

byte[] data = body.toString().getBytes();

try {

URL url = new URL(urlPath);

//获得URL对象

connection = (HttpURLConnection) url.openConnection();

//获得HttpURLConnection对象

connection.setRequestMethod("POST");

// 设置请求方法为post

connection.setUseCaches(false);

//不使用缓存

connection.setConnectTimeout(10000);

//设置超时时间

connection.setReadTimeout(10000);

//设置读取超时时间

connection.setDoInput(true);

//设置是否从httpUrlConnection读入,默认情况下是true;

connection.setDoOutput(true);

//设置为true后才能写入参数

connection.setRequestProperty("Content-Type",

"application/x-www-form-urlencoded");

connection.setRequestProperty("Content-Length", String.valueOf(data.length));

os = connection.getOutputStream();

os.write(data);

//写入参数

if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {

//相应码是否为200

is = connection.getInputStream();

//获得输入流

BufferedReader reader = new BufferedReader(new InputStreamReader(is));

//包装字节流为字符流

StringBuilder response = new StringBuilder();

String line;

while ((line = reader.readLine()) != null) {

response.append(line);

}

return response.toString();

}

} catch (Exception e) {

e.printStackTrace();

} finally {

//关闭

if (os != null) {

try {

os.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if (is != null) {

try {

is.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if (connection != null) {

connection.disconnect();

connection = null;

}

}

return null;

}

private StringBuffer getParamString(Map params) {

StringBuffer result = new StringBuffer();

Iterator> iterator = params.entrySet().iterator();

while (iterator.hasNext()) {

Map.Entry param = iterator.next();

String key = param.getKey();

String value = param.getValue();

result.append(key).append('=').append(value);

if (iterator.hasNext()) {

result.append('&');

}

}

return result;

}

以上代码参考了部分LessCode项目

HttpClient

特点

高效稳定,但是维护成本高昂,故android 开发团队不愿意在维护该库而是转投更为轻便的HttpUrlConnection

用法

由于在android2.3之后就被HttpUrlConnection取代了,这里也不过多介绍了,不过当初学习它的时候还没接触到其他库,就感觉它好方便,下面简单贴出使用方法

GET

[java] view plain copy 在CODE上查看代码片派生到我的代码片

private String get(String url){

HttpClient client=null;

HttpGet request=null;

try {

client=new DefaultHttpClient();

request=new HttpGet(url);

HttpResponse response=client.execute(request);

if(response.getStatusLine().getStatusCode()== HttpStatus.SC_OK){

String result=EntityUtils.toString(response.getEntity(),"UTF-8");

return result;

}

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

POST

[java] view plain copy 在CODE上查看代码片派生到我的代码片

private String post(String url,List params){

HttpClient client=null;

HttpPost request=null;

try {

client=new DefaultHttpClient();

request=new HttpPost(url);

request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));

HttpResponse response=client.execute(request);

if(response.getStatusLine().getStatusCode()== HttpStatus.SC_OK){

String result=EntityUtils.toString(response.getEntity(),"UTF-8");

return result;

}

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

以上代码参考了郭霖《第一行代码》——HttpClient部分

Android Asynchronous Http Client

Android Asynchronous Http Client一看名字就知道它是基于Http Client的,但是呢在安卓中Http Client已经废弃了,所以也不建议使用这个库了。然后仍然有一些可取的内容值得学习,所以这里也介绍一下。

特点

所以请求在子线程中完成,请求回调在调用该请求的线程中完成

使用线程池

使用RequestParams类封装请求参数

支持文件上传

持久化cookie到SharedPreferences,个人感觉这一点也是这个库的重要特点,可以很方便的完成一些模拟登录

支持json

支持HTTP Basic Auth

用法

编写一个静态的HttpClient

[java] view plain copy 在CODE上查看代码片派生到我的代码片

package https://www.360docs.net/doc/e77574705.html,.zafu.http;

import com.loopj.android.http.AsyncHttpClient;

import com.loopj.android.http.AsyncHttpResponseHandler;

import com.loopj.android.http.RequestParams;

/**

* Created by lizhangqu on 2015/5/7.

*/

public class TestClient {

private static final String BASE_URL = "http://121.41.119.107/";

private static AsyncHttpClient client = new AsyncHttpClient();

public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {

client.get(getAbsoluteUrl(url), params, responseHandler);

}

public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {

client.post(getAbsoluteUrl(url), params, responseHandler);

}

private static String getAbsoluteUrl(String relativeUrl) {

return BASE_URL + relativeUrl;

}

}

调用get或者post方法

参数通过RequestParams传递,没有参数则传递null

[java] view plain copy 在CODE上查看代码片派生到我的代码片

RequestParams params = new RequestParams();

params.put("","");

如果要保存cookie,在发起请求之前调用以下代码

[html] view plain copy 在CODE上查看代码片派生到我的代码片PersistentCookieStore myCookieStore = new PersistentCookieStore(this);

client.setCookieStore(myCookieStore);

之后请求所得到的cookie都会自动持久化

如果要自己添加cookie,则调用以下代码

[java] view plain copy 在CODE上查看代码片派生到我的代码片

BasicClientCookie newCookie = new BasicClientCookie("cookiesare", "awesome"); newCookie.setVersion(1);

newCookie.setDomain("https://www.360docs.net/doc/e77574705.html,");

newCookie.setPath("/");

myCookieStore.addCookie(newCookie);

使用

在回调函数中处理返回结果

[java] view plain copy 在CODE上查看代码片派生到我的代码片

private void get(){

TestClient.get("test/index.php", null, new AsyncHttpResponseHandler() {

@Override

public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {

}

@Override

public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {

}

});

}

private void post(){

RequestParams params = new RequestParams();

params.put("user","asas");

params.put("pass","12121");

params.put("time","1212121");

TestClient.post("test/login.php", params, new AsyncHttpResponseHandler() {

@Override

public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {

}

@Override

public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {

}

});

}

以上代码参考了Android Asynchronous Http Client官方实例

V olley

既然在android2.2之后不建议使用Http Client,那么有没有一个库是android2.2及以下版本使用Http Client,而android2.3及以上版本使用HttpUrlConnection的呢,答案是肯定的,就是Volley,它是android开发团队在2013年Google I/O大会上推出了一个新的网络通信框架V olley可以说是把AsyncHttpClient和Universal-Image-Loader的优点集于了一身,既可以像AsyncHttpClient一样非常简单地进行HTTP通信,也可以像Universal-Image-Loader一样轻松加载网络上的图片。除了简单易用之外,V olley在性能方面也进行了大幅度的调整,它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络

操作,比如说下载文件等,V olley的表现就会非常糟糕

特点

用法

下面一步一步来学习其用法

GET

[java] view plain copy 在CODE上查看代码片派生到我的代码片

private void get(){

RequestQueue queue= Volley.newRequestQueue(getApplicationContext());

String url="http://121.41.119.107/test/index.php";

StringRequest request=new StringRequest(url, new Response.Listener() { @Override

public void onResponse(String response) {

Log.d("TAG",response);

}

}, new Response.ErrorListener() {

@Override

public void onErrorResponse(V olleyError error) {

}

});

queue.add(request);

}

POST

通过指定请求方法为Request.Method.POST使其成为post请求,然后重新getParams方法设置请求参数。当发出POST请求的时候,V olley会尝试调用StringRequest的父类——Request 中的getParams()方法来获取POST参数

[java] view plain copy 在CODE上查看代码片派生到我的代码片

private void post() {

RequestQueue queue = V olley.newRequestQueue(getApplicationContext());

String url = "http://121.41.119.107/test/login.php";

StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener() {

@Override

public void onResponse(String response) {

Log.d("TAG", response);

}

}, new Response.ErrorListener() {

@Override

public void onErrorResponse(V olleyError error) {

}

}) {

//重写getParams方法设置参数

@Override

protected Map getParams() throws AuthFailureError {

Map params = new HashMap();

params.put("user", "asas");

params.put("pass", "12121");

params.put("time", "1212121");

return params;

}

};

queue.add(request);

}

加载图片

加载图像的方法和前面类似,只不过不在是StringRequest而是ImageRequest。

[java] view plain copy 在CODE上查看代码片派生到我的代码片

private void getImage() {

RequestQueue queue = V olley.newRequestQueue(getApplicationContext());

String url = "https://https://www.360docs.net/doc/e77574705.html,/img/bdlogo.png";

//第三第四个参数分别用于指定允许图片最大的宽度和高度,如果指定的网络图片的宽度或高度大于这里的最大值,则会对图片进行压缩,指定成0的话就表示不管图片有多大,都不会进行压缩。

//第五个参数就是ImageView里中的属性ScaleType

//第六个参数用于指定图片的颜色属性

ImageRequest request = new ImageRequest(url, new Response.Listener() { @Override

public void onResponse(Bitmap response) {

ImageView iv= (ImageView) findViewById(R.id.iv);

iv.setImageBitmap(response);

}

}, 0, 0, ImageView.ScaleType.CENTER, Bitmap.Config.ARGB_8888, new Response.ErrorListener() {

@Override

public void onErrorResponse(V olleyError error) {

}

});

queue.add(request);

}

其实加载图片的功能还远远不止这些,使用ImageLoader可以实现对图片的缓存,还可以过滤重复链接,避免发送重复的请求

ImageLoader的使用方法概括为以下几步

1. 创建一个RequestQueue对象。

2. 创建一个ImageLoader对象。

3. 获取一个ImageListener对象。

4. 调用ImageLoader的get()方法加载网络上的图片。

[java] view plain copy 在CODE上查看代码片派生到我的代码片

//继承ImageCache,使用LruCache实现缓存

public class BitmapCache implements ImageLoader.ImageCache {

private LruCache mCache;

public BitmapCache() {

int maxSize = 10 * 1024 * 1024;

mCache = new LruCache(maxSize) {

@Override

protected int sizeOf(String key, Bitmap bitmap) {

return bitmap.getRowBytes() * bitmap.getHeight();

}

};

}

@Override

public Bitmap getBitmap(String url) {

return mCache.get(url);

}

@Override

public void putBitmap(String url, Bitmap bitmap) {

mCache.put(url, bitmap);

}

}

private void getImageByImageLoader() {

ImageView iv= (ImageView) findViewById(R.id.iv);

RequestQueue queue = V olley.newRequestQueue(getApplicationContext());

String url = "https://https://www.360docs.net/doc/e77574705.html,/img/bdlogo.png";

ImageLoader loader=new ImageLoader(queue,new BitmapCache() );

// 第一个参数指定用于显示图片的ImageView控件

// 第二个参数指定加载图片的过程中显示的图片

// 第三个参数指定加载图片失败的情况下显示的图片

ImageLoader.ImageListener

listener=ImageLoader.getImageListener(iv,R.mipmap.ic_launcher,R.mipmap.ic_launcher);

// 调用ImageLoader的get()方法来加载图片

// 第一个参数就是图片的URL地址

// 第二个参数则是刚刚获取到的ImageListener对象

// 如果想对图片的大小进行限制,也可以使用get()方法的重载,指定图片允许的最大宽度和高度,即通过第三第四个参数指定

loader.get(url,listener);

}

最后,V olley提供了一种自定义ImageView来加载图片,其使用方法可概括为

1. 创建一个RequestQueue对象。

2. 创建一个ImageLoader对象。

3. 在布局文件中添加一个NetworkImageView控件。

4. 在代码中获取该控件的实例。

5. 设置要加载的图片地址。

我们在布局中申明该控件

[html] view plain copy 在CODE上查看代码片派生到我的代码片

android:id="@+id/network_image_view"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

/>

在程序中实现加载

[java] view plain copy 在CODE上查看代码片派生到我的代码片

public void networkImageView(){

RequestQueue queue = V olley.newRequestQueue(getApplicationContext());

ImageLoader loader=new ImageLoader(queue,new BitmapCache() );

NetworkImageView niv= (NetworkImageView) findViewById(https://www.360docs.net/doc/e77574705.html,work_image_view);

niv.setDefaultImageResId(R.mipmap.ic_launcher);//设置加载中显示的图片

niv.setErrorImageResId(R.mipmap.ic_launcher);//设置加载失败时显示的图片

niv.setImageUrl("https://https://www.360docs.net/doc/e77574705.html,/img/bdlogo.png", loader);//设置目标图片的URL地址

}

自定义Request

在实际应用中,往往需要将http请求与json进行集成,而Volley正恰恰支持这样的方式,不过需要我们自己自定义Request,这里我们使用google的Gson库进行集成。

1. 继承Request类

2. 重写parseNetworkResponse,实现json与实体类转换,由于实体类未定,所以采用泛型下文用到的json字符串如下

{"name":"https://www.360docs.net/doc/e77574705.html,hangqu","age":16}

[java] view plain copy 在CODE上查看代码片派生到我的代码片

package https://www.360docs.net/doc/e77574705.html,.zafu.http;

import https://www.360docs.net/doc/e77574705.html,workResponse;

import com.android.volley.ParseError;

import com.android.volley.Request;

import com.android.volley.Response;

import com.android.volley.toolbox.HttpHeaderParser;

import com.google.gson.Gson;

import java.io.UnsupportedEncodingException;

/**

* Created by lizhangqu on 2015/5/7.

*/

public class GsonRequest extends Request {

private final Response.Listener mListener;

private Gson mGson;

private Class mClass;

public GsonRequest(int method, String url, Class clazz, Response.Listener listener,

Response.ErrorListener errorListener) {

super(method, url, errorListener);

mGson = new Gson();

mClass = clazz;

mListener = listener;

}

public GsonRequest(String url, Class clazz, Response.Listener listener,

Response.ErrorListener errorListener) {

this(Method.GET, url, clazz, listener, errorListener);

}

@Override

protected Response parseNetworkResponse(NetworkResponse response) { try {

String jsonString = new String(response.data,

HttpHeaderParser.parseCharset(response.headers));

return Response.success(mGson.fromJson(jsonString, mClass),

HttpHeaderParser.parseCacheHeaders(response));

} catch (UnsupportedEncodingException e) {

return Response.error(new ParseError(e));

}

}

@Override

protected void deliverResponse(T response) {

mListener.onResponse(response);

}

}

编写测试实体类,两个字段一个name一个age

[java] view plain copy 在CODE上查看代码片派生到我的代码片

package https://www.360docs.net/doc/e77574705.html,.zafu.http;

/**

* Created by lizhangqu on 2015/5/7.

*/

public class Person {

private String name;

private int age;

public String getName() {

return name;

}

public void setName(String name) {

https://www.360docs.net/doc/e77574705.html, = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

@Override

public String toString() {

return "Person{" +

"name='" + name + '\'' +

", age=" + age +

'}';

}

}

调用方法和StringRequest是一样的。如下所示

[html] view plain copy 在CODE上查看代码片派生到我的代码片

private void json(){

RequestQueue queue = V olley.newRequestQueue(getApplicationContext());

GsonRequest request=new GsonRequest(url, Person.class, new Response.Listener() {

@Override

public void onResponse(Person response) {

Log.d("TAG",response.toString());

}

}, new Response.ErrorListener() {

@Override

public void onErrorResponse(V olleyError error) {

}

});

queue.add(request);

}

以上代码参考了郭霖三篇V olley博客文章,分别为

Android V olley完全解析(一),初识V olley的基本用法

Android V olley完全解析(二),使用V olley加载网络图片

Android V olley完全解析(三),定制自己的Request

okHttp

okhttp 是一个Java 的HTTP+SPDY 客户端开发包,同时也支持Android。需要Android 2.3以上。

特点

OKHttp是Android版Http客户端。非常高效,支持SPDY、连接池、GZIP和HTTP 缓存。默认情况下,OKHttp会自动处理常见的网络问题,像二次连接、SSL的握手问题。

如果你的应用程序中集成了OKHttp,Retrofit默认会使用OKHttp处理其他网络层请求。

从Android4.4开始HttpURLConnection的底层实现采用的是okHttp.

用法

[java] view plain copy 在CODE上查看代码片派生到我的代码片

private String get(String url) {

OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()

.url(url)

.build();

Response response = null;

try {

response = client.newCall(request).execute();

return response.body().string();

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

POST

POST需要使用RequestBody对象,之后再构建Request对象时调用post函数将其传入即可

[java] view plain copy 在CODE上查看代码片派生到我的代码片

private String post(String url) {

OkHttpClient client = new OkHttpClient();

RequestBody formBody = new FormEncodingBuilder()

.add("user", "Jurassic Park")

.add("pass", "asasa")

.add("time", "12132")

.build();

Request request = new Request.Builder()

.url(url)

.post(formBody)

.build();

Response response = null;

try {

response = client.newCall(request).execute();

return response.body().string();

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

此外,post的使用方法还支持文件等操作,具体使用方法有兴趣的可以自行查阅

对Gson的支持

okHttp还自带了对Gson的支持

[java] view plain copy 在CODE上查看代码片派生到我的代码片

private Person gson(String url){

OkHttpClient client = new OkHttpClient();

Gson gson = new Gson();

Request request = new Request.Builder()

.url(url)

.build();

Response response = null;

try {

response = client.newCall(request).execute();

Person person = gson.fromJson(response.body().charStream(), Person.class);

return person;

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

异步操作

以上的两个例子必须在子线程中完成,同时okHttp还提供了异步的方法调用,通过使用回调来进行异步调用,然后okHttp的回调依然不在主线程中,因此该回调中不能操作UI [java] view plain copy 在CODE上查看代码片派生到我的代码片

private void getAsync(String url) {

OkHttpClient client = new OkHttpClient();

https://www.360docs.net/doc/e77574705.html,est request = new Request.Builder()

.url(url)

.build();

Response response = null;

client.newCall(request).enqueue(new Callback() {

@Override

public void onFailure(Request request, IOException e) {

}

@Override

public void onResponse(Response response) throws IOException {

String result = response.body().string();

Toast.makeText(getApplicationContext(),result,Toast.LENGTH_SHORT).show();

//不能操作ui,回调依然在子线程

Log.d("TAG", result);

}

});

}

okHttp的使用还有很多内容,这里也不过多介绍,更多内容,参考官方网址

Retrofit

特点

使用

Retrofit支持同步和异步两种方式,在使用时,需要将请求地址转换为接口,通过注解来指定请求方法,请求参数,请求头,返回值等信息。还是使用之前的person的那段json值,get请求到服务器后从数据库查询数据,返回值为查询到的数据,post请求向服务器提交一条数据,返回值为提交的数据。

首先完成请求所用的service,是一个interface,完全通过注解完成配置

[java] view plain copy 在CODE上查看代码片派生到我的代码片

package https://www.360docs.net/doc/e77574705.html,.zafu.http;

import retrofit.Callback;

import retrofit.http.Field;

import retrofit.http.FormUrlEncoded;

import retrofit.http.GET;

import retrofit.http.Headers;

import retrofit.http.POST;

import retrofit.http.Path;

import retrofit.http.Query;

/**

* Created by lizhangqu on 2015/5/11.

*/

public interface PersonService {

@Headers({

"Cache-Control: max-age=640000",

"User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"

})

//通过注解设置请求头

@GET("/{test}/rest.php")

//设置请求方法为get,相对路径为注解内内容,其中{test}会被@Path注解指定内容替换

Person getPerson(@Path("test") String dir,@Query("name") String name);

//@Query用于指定参数

@FormUrlEncoded

//urlencode

@POST("/test/rest1.php")

//post提交

Person updatePerson(@Field("name") String name,@Field("age") int age);

//@Field提交的域

@POST("/test/rest1.php")

void updatePerson(@Field("name") String name,@Field("age") int age, Callback callback);

//异步回调,不能指定返回值

}

GET

使用时,通过RestAdapter的实例获得一个接口的实例,其本质是动态代理,注意含有返回值的方法是同步的,不能UI线程中调用,应该在子线程中完成

[java] view plain copy 在CODE上查看代码片派生到我的代码片

RestAdapter restAdapter = new RestAdapter.Builder()

.setEndpoint("http://121.41.119.107")

.build();

PersonService personService=restAdapter.create(PersonService.class);

Person person=personService.getPerson("test","zhangsan");

Log.d("TAG",person.toString());

POST

POST的调用同Get,获得adapter后获得一个代理对象,然后通过这个代理对象进行网络请求

[java] view plain copy 在CODE上查看代码片派生到我的代码片

Person person1=personService.updatePerson("lizhangqu", 12);

Log.d("TAG",person1.toString());

异步请求

如果要使用异步请求,需要将接口中的方法返回值修改会void,再加入回调参数Callback,就如PersonService中第三个方法一样,请求完成后会回调该callback对象的success或者fail 方法。

[java] view plain copy 在CODE上查看代码片派生到我的代码片

RestAdapter restAdapter = new RestAdapter.Builder()

.setEndpoint("http://121.41.119.107")

.build();

PersonService personService=restAdapter.create(PersonService.class);

personService.updatePerson("lizhangqu",23, new Callback() {

@Override

public void success(Person person, Response response) {

Log.d("TAG", person.toString());

}

@Override

public void failure(RetrofitError error) {

}

});

Retrofit的使用还有很多内容,剩下的就留给各位读者自行去发现了,而其官网页提供了及其详细的说明。下面提供官方网址

retrofit官网示例

这个库里面有很多精华的内容,建议各位仔细的阅读下官方的文档。

RoboSpice

见之前写的一篇博文

RoboSpice:android异步网络库简单用法

总结

网络请求库多种多样,最终其本质思想是一致的,要学会融汇贯通,还是要fucking the source code。由于本篇文章已经过长,所以图片的网络加载准备另开一篇博客进行整理。

安卓手机数据库连接代码

package com.fenghuo.firstproject; import android.app.Activity; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.widget.CursorAdapter; import android.widget.ListView; import android.widget.SimpleCursorAdapter; public class DataBaseActivity extends Activity { public static SQLiteDatabase db = null; private ListView listView = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(https://www.360docs.net/doc/e77574705.html,yout.activity_data_base); SQLiteOpenHelper helper = new SQLiteOpenHelper(this,"mydb",null,1) { @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("drop table users"); onCreate(db); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE 'users' ( '_id' INTEGER NOT NULL, 'username' TEXT NOT NULL, 'password' TEXT NOT NULL, 'email' TEXT NOT NULL, PRIMARY KEY ('_id') ) "); db.execSQL("insert into users values(1,'admin','admin','admin@https://www.360docs.net/doc/e77574705.html,')"); db.execSQL("insert into users values(2,'admin1','admin','admin1@https://www.360docs.net/doc/e77574705.html,')"); db.execSQL("insert into users values(3,'admin2','admin','admin2@https://www.360docs.net/doc/e77574705.html,')"); db.execSQL("insert into users values(4,'admin3','admin','admin3@https://www.360docs.net/doc/e77574705.html,')"); } };

Android创建和使用数据库详细指南

Android创建和使用数据库详细指南(1) 摘要:每个应用程序都要使用数据,Android应用程序也不例外,Android使用开源的、与操作系统无关的SQL数据库--SQLite,本文介绍的就是如何为你的Android应用程序创建和操作SQLite数据库。 数据库支持每个应用程序无论大小的生命线,除非你的应用程序只处理简单的数据,那么就需要一个数据库系统存储你的结构化数据,Android使用SQLite数据库,它是一个开源的、支持多操作系统的SQL数据库,在许多领域广泛使用,如Mozilla FireFox就是使用SQLite 来存储配置数据的,iPhone也是使用SQLite来存储数据的。 在Android中,你为某个应用程序创建的数据库,只有它可以访问,其它应用程序是不能访问的,数据库位于Android设备/data/data//databases文件夹中,在这篇文章中,你将会学习到如何在Android中创建和使用数据库。 1SQLite数据库 使用Eclipse创建一个Android项目,取名为Database,如图1所示: 图1 数据库-使用Eclipse创建你的Android新项目

2创建DBAdapter辅助类 接下来创建一个数据库,取名为bookstitles,字段如图2所示。 图2 数据库字段在DBAdapter.java文件中,定义清单1中的常量。 清单1 定义DBAdapter.java文件中的常量 package net.learn2develop.Database; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper;

基于Android平台的无线WiFi控制方法_王雷概要

文章编号:1007-757X(20127-0058-04 基于Android平台的无线WiFi控制方法 王雷,蓝箭,陈雪娟,陈峰 摘要:提出了一种基于Android手机的无线WiFi控制系统。首先采用嵌入式ARM9为硬件控制模块,手机终端以Android 为应用程序的开发,编写了一个手机客户端软件,完成了手机端与控制器端之间的数据传输,实现了手机远程对PWM调速等的控制。系统中Android手机可利用周围无线网络资源与其他设备进行交互并实施控制,不仅为现有智能控制系统提供了新的控制方法,也为实现机器与人的信息交换提供了新的交互手段。 关键词:Android;嵌入式系统;WiFi;PWM控制 中图分类号:TP399 文献标志码:B Control Method Based on WiFi in Android Wang Lei, Lan Jian, Chen XueJuan, Chen Feng (School of Mechatronics Engineering and Automation, Shanghai University, Shanghai 200072, China Abstract:The paper presents a wireless WiFi control system based on phones with Android system The system was builded with embedded technology based on ARM9 hardware control module to develop the Android application for mobile terminal and a cell phone client application, which is used to complete data transfer between the mobile terminal and the controller that enables the cell phone to control the speed of device with PWM method. Android phone use the wireless network resources around to interact with and control other devices. This not only provides a new control method for existing intelligent control system, but also a new interac-tive approach of information exchange for HMI.

Android学习笔记---SQLite介绍,以及使用Sqlite,进行数据库的创建,完成数据添删改查的理解

Android学习笔记---SQLite介绍,以及使用Sqlite,进行数据库的创建,完成数据添删改查的理解 17_创建数据库与完成数据添删改查--------------------------------------1.SQLite介绍:最大特点是,无数据类型; 除了可以使用文件或SharedPreferences存储数据,还可以选择使用SQLite数据库存储数据。在Android平台上,集成了一个嵌入式关系型数据库—SQLite,SQLite3支持 NULL、INTEGER n n 、REAL(浮点数字)、TEXT(字符串文本)和BLOB(二进制对象)数据类型,虽然它支持的类型 n n 只有五种,但实际上sqlite3也接受varchar(n)、char(n)、decimal(p,s) 等数据类型,只不 n n 过在运算或保存时会转成对应的五种数据类型。 SQLite最大的特点是你可以把各种类型的数n n 据保存到任何字段中,而不用关心字段声明的数据类型是什么。例如:可以在Integer类型的 n n 字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值。n n n 但有一种情况例外:定义为INTEGER PRIMARY KEY的字段只能存储64位整数, 当向这种字段 n n 保存除整数以外的数据时,将会产生错误。 另外, SQLite 在解析CREATE TABLE 语句时, n n 会忽略 CREATE TABLE 语句中跟在字段名后面的数据类型信息,如下面语句会忽略 name字段 n n 的类型信息: CREATE TABLE person (personid integer primary key autoincrement, name varchar n n (20)) SQLite可以解析大部分标准SQL语句,如:查询语句:select * from 表名 where 条件子句 group by 分组字句 having ... order byn n n 排序子句如:select * from person n n n n select * from person order by id desc n n n n select name from person group by name having count(*)>1 ---------------------------------------------------------------------------2.a.分页SQL与mysql类似,下面SQL语句获取5条记录,跳过前面3条记录n n select * from Account limit 5 offset 3 或者 select * from Account limit 3,5 n b.select * from Account limit 3,5,指的是跳过前面的3条记录,然后获取5条记录n c.select * from Account limit 3,5是select * from Account limit 5 offset 3语句 n n 的简写版 -------------------------------------------------------------------------------n 3.常用操作: a.插入语句:insert into 表名(字段列表) values(值列表)。如: insert into person nn n n (name, age) values(‘传智’,3) b.更新语句:update 表名 set 字段名=值where 条件子句。如:update person set name=n n n n'credream ‘where id=10 c.删除语句:delete from 表名 where 条件子句。如:delete from person nwhere id=10 -------------------------------------------------------------------------------2.虽然无数据类型,但是建议加上,这样可以增加可读性,支持标准sql,oracle中的不行 ---------------------------------------------------3.获取添加记录后的自增长的ID值:select last_insert_rowid(); -----------------------------------------------------------4.在android中开发数据库应用: n a.创建数据库:以前在javaee时候,需要手工数据,但是android应用,需要运行在用户的 n n 手机上,所以,android应用,要有自动创建数据库功能,当第一次使用软件的时候 n n 就创建数据库----------------------------------------5.关于数据库自动创建的详细介绍: 我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很 n n 多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用软件时创建出 n n 应用使用到的数据库表结构及添加一些初始化记录,另外在软件升级的时候,也需要对数据 n n 表结构进行更新。那么,我们如何才能实现在用户初次使用或升级软件时自动在用户的手机 n n 上创建出应用需要的数据库表呢?总不能让我们在每个需要安装此软件的手机上通过手工方 n n 式创建数据库表吧?因为这种需求是每个数据库应用都要面临的,所以在Android系统,为我 n n 们提供了一个名为SQLiteOpenHelper的抽象类,必须继承它才能使用,它是通过对数据库版 n n 本进行管理来实现前面提出的需求。n -----------------------------------------6.SQLite数据库添加,删除,改查操作 n A.创建数据库:SQLiteOpenHelper .getWritableDatabase ()或getReadableDatabase() n n 可以创建数据库7.创建完成以后可以使用SQLITE Expert软件打开生成的数据库n 可以看到除了生成的自己的需要的表之外,还生成了一张:android_metadata表: n 如果在sqlite中使用数据库一定会有一张android_metadata表,用来登记用户的 n 使用语言:zh_cn -----------------------------------------------------n b.数据库自动创建的过程及方法详细介绍: n n我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在 n n 很多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用软件时创建 n n 出应用使用到的数据库表结构及添加一些初始化记录,另外在软件升级的时候,也需要对数n n 据表结构进行更新。那么,我们如何才能实现在用户初次使用或升级软件时自动在用户的手 n n 机上创建出应用需要的数据库表呢?总不能让我们在每个需要安装此软件的手机上通过手工 n n 方式创建数据库表吧?因为这种需求是每个数据库应用都要面临的,所以在Android系统,为n n 我们提供了一个名为SQLiteOpenHelper的抽象类,必须继承它才能使用,它是通过对数据库n n 版本进行管理来实现前面提出的需求。n -------------------------------------------8.详细介绍: 为了实现对数据库版本进行管理,SQLiteOpenHelper类提供了两个重要的方法,分别是 n n onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabase db, int oldVersion, intn n n newVersion),前者用于初次使用软件时生成数据库表,后者用于升级软件时更新数据库表结n n 构。当调用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法获n n 取用于操作数据库的SQLiteDatabase实例的时候,如果数据库不存在,Android系统会自动生 n n 成一个数据库,接着调用onCreate()方法,onCreate()方法在初次生成数据库时才会被调用 n n ,在onCreate()方法里可以生成数据库表结构及添加一些应用使用到的初始化数据。 n n onUpgrade()方法在数据库的版本发生变化时会被调用,一般在软件升级时才需改变版本号, n n 而数据库的版本是由程序员控制的,假设数据库现在的版本是1,由于业务的变更,修改了数n n 据库表结构,这时候就需要升级软件,升级软件时希望更新用户手机里的数据库表结构,为n n 了实现这一目的,可以把原来的数据库版本设置为2(有同学问设置为3行不行?当然可以,如 n n 果你愿意,设置为100也行),并且在onUpgrade()方法里面实现表结构的更新。当软件的版本 n n 升级次数比较多,这时在onUpgrade()方法里面可以根据原版号和目标版本号进行判断,然后 n n 作出相应的表结构及数据更新。 getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的 n n SQLiteDatabase实例。但getWritableDatabase() 方法以读写方式打开数据库,一旦数据库n n 的磁盘空间满了,数据库就只能读而不能写,倘若使用的是getWritableDatabase() 方法就 n n 会出错。getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了 n n ,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。 ------------------------------------------------------------------------9.创建数据库的代码: n a.创建项目:DBSQLIte n b./DBSQLIte/src/com/credream/service/DBOpenHelter.java n n package com.credream.service; n n import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteDatabase.CursorFactory; n n public class DBOpenHelter extends SQLiteOpenHelper { //父类没有默认构造器,需要显示调用 public DBOpenHelter(Context context) { super (context, "credream.db", null, 1); //数据库创建完成后,默认会保存在<包>/database/文件夹下 //当修改版本号时候,会触发:onUpgrade方法 //第二个:指定数据库名称, //第三个:游标工厂,用来迭代,查询后的结果集,null代表使用系统默认的 n n 游标工厂//版本号,大于0 n } /** n* 这个方法是在数据库第一次被创建的时候调用的 n*/ @Override public void onCreate(SQLiteDatabase db) { //SQLiteDatabase这个类,封装了增删改查操作,也叫做数据库操作实例 db.execSQL("CREATE TABLE person (personid integer primary keyn n n autoincrement, name varchar(20))"); //这里也可以不写name的数据类型,因为sqlite是数据类型无关的,就是写n n 了varchar(20),也可以写入超过20的内容 n n } /** n* 当数据库的版本号变更的时候被调用 n*/ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("alter table person add phone varchar(12) null"); n n } n n } --------------------------------------------------------2.在清单文件中写入测试环境 n n n n n n n n n n ---------------------------------------------------- 3./DBSQLIte/src/com/credream/test/PersonServiceTest.java package com.credream.test; n n import com.credream.service.DBOpenHelter; n n import android.test.AndroidTestCase; n n public class PersonServiceTest extends AndroidTestCase { //创建数据库,在<包>/database/ public void testCreateDB(){ DBOpenHelter dbOpenHelter=new DBOpenHelter(getContext()); dbOpenHelter.getWritableDatabase(); n } n n } -------------------------------------------------------4.选择方法开始测试,然后,在data/data/<包>/database/下 n 查看并用sqlite打开生成的数据库检查是否正确---------------------------------------------然后将版本号,改成2,然后再次执行,看到,表已经被更新,增加了一列phone -----------------------------------------------5.了解sqlite工作的原理: n DBOpenHelter dbOpenHelter=new DBOpenHelter(getContext()); dbOpenHelter.getWritableDatabase(); n 打开getWritableDatabase();代码:

移动互联网应用开发-Android网络编程基础实验

西安邮电大学 通信与信息工程学院 实验报告 (2018/ 2019学年第 2 学期) 课程名称:移动互联网应用开发 实验名称:Android网络编程基础实验 组成员/学号: 专业/班级:通信工程1612 指导教师:金蓉 实验时间:2019年5月14日 一、实验目的和要求

1、掌握基于串口通信的Android应用程序的开发方法 2、掌握基于多线程的Android应用程序的设计开发方法 3、掌握基于socket套接字的Android应用程序的设计开发方法 二、实验原理 1、串口通信 串行端口(SeiailPort)简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。申行接口是指数据一位一位地顺序传送,其特点 是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线), 从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。 串口通信用于ASCII码字符的传输。通信使用3根线完成,分别是地线(GND)、发送(TX)、 接收(RX)。由于串口通信是异步模式,端口能够在一根线上发送数据同时在另一根线上 接收数据。串口通信最重要的参数是波特率、数据位、停止价和奇偶校验。对于两个进行 通信的端口,这些参数必须匹配。 因为串口通信涉及到底层比较难,所以谷歌封装了一个比较简单的方法串口类android-serialport-api,只要四步我们就可以使用该串口:1)打开串口(及配置串口); 2)读串口;3)写串口;4)关闭串口。 2、多线程 多线程,是指从软件或者硬件上实现多个线程并发执行的技术。当用户需要执行一些耗时操作,比如发起一条网络请求时,考虑到网速等其他因素,服务器未必会立刻响应请求,那么就必须将这类操作放在子线程中运行,这就需要实现多线程编程。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。在一个程序中,这些独立运行的程序片段叫作“线程”(Thread),利用Thread 编程的概念就叫作“多线程处理(Multithreading)”。Android多线程编程与Java 多线程编程语法相同。 线程: Android 中的线程是Android程序执行流的最小单元,即安卓CPU分配的最小单元是线程。 当应用程序启动时,Android 首先会开启一个主线程(也就是UI线程),主线程为管理界面中的UI控件,进行事件分发。Thead.currentThread()是当前线程 安卓新建线程的两种方法: 1) new Thread(new Runnable(){ @Override

一个典型的数据库设计实例pos_sales

超市POS管理系统 数据库设计 数据库在一个信息管理系统中占有非常重要的地位,数据库结构的设计好坏将直接对应用系统的效率以及实现的效果产生影响。数据库设计一般包括以下四个部分:数据库需求分析、数据库概念结构设计、数据库逻辑结构设计、数据库物理结构实现。 一、数据库需求分析 通过对超市管理工作过程的内容和数据流图分析,设计如下面的数据项和数据结构。 1、员工信息,包括的数据项有:员工编号,姓名,性别,职务,口令,权限级别、身份证号,所属部门编号等。 2、部门信息,包括的数据项有:部门编号,部门名称。 3、供应商信息,包括的数据项有:供应商编号,供应商名称,地址,邮政编码,电话号码,税号,银行帐号,开户银行,联系人,备注等。 4、会员信息,包括的数据项有:会员编号,姓名,性别,身份证号,消费总金额,积分等。 5、入库信息,包括的数据项有:入库编号,入库日期,商品编号,计量单位,入库价格,销售价格,数量,总金额,供应商编号,业务员编号等。 6、商品信息,包括的数据项有:商品编号,所属类别,数量,单价,商品名称等。 7、销售出货单主信息,包括的数据项有:销售日期,总金额,是否现金,是否会员,会员编号、收银号编号等。 8、销售出货单子信息,包括的数据项有:商品编号,数量,单价,折扣比例,金额等。 二、数据库概念结构设计 根据上面设计规划出的实体,我们对各个实体具体的描述E-R图如下:

图1 员工信息E-R图 图2 部门信息E-R图 图3 入库信息E-R图 图4 商品信息E-R图

图5 销售出货单主信息E-R图 图6 销售出货单子信息E-R图 图7 会员信息E-R图 图8 供应商信息E-R图

Android移动应用开发实验指导书

《Android移动应用开发》 实验指导书 课程代码: 总课时数: 适用专业: 院(系)名称:

实验一深入理解Activity 目标 (1)掌握Activity的开发、配置和使用。 (2)掌握Intent的几种常用的属性。 (3)Android系统内置Intent的使用。 (4)了解Activity的生命周期 实验软、硬件环境 硬件:PC电脑一台; 配置:winxp或win7系统,内存大于4G,硬盘250G及以上 JDK1.7 、Eclipse、ADT、Android SDK 实验主要技术基础 (1)活动是Android的四大组件之一,它是一种可以包含用户界面的组件,主要用于和用户进行交互。 (2)Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。 任务 1、请在AndroidManifest.xml文件中配置SecondActivity: 配置Intent的Action属性为com.sise.intent.action.JHY_ACTION; 配置Category属性为com.sise.intent.category.JHY_CATEGORY。 通过隐式Intent的使用从FirstActivity启动SecondActivity,编写代码,运行程序,预期效果如下所示。

图1 程序运行初始化界面图2 点击图1中的按钮后的运行结果 2、请使用显式Intent启动SecondActivity,并使用Intent从FirstActiv传递数据到SecondActivity。编写代码,运行程序,预期效果如下所示。 图1 程序运行初始化界面图2 点击图1中的按钮后的运行结果 3、使用Intent传递数据从SecondActivity返回数据到FirstActivity中去。编写代码,运行程序,预期效果如下所示。 图1 程序运行初始化界面图2 点击图1按钮运行结果 图3 点击图2按钮运行结果 实验方法与步骤 (1)创建活动 Activity是Android系统提供的一个活动基类所有的活动都必须直接或间接继承此类才能拥有活动的特性。 (2)布局文件 创建布局文件 加载布局文件 (3)在清单文件中注册活动 (4)以上方法完成多个活动的创建 (5)使用Intent完成多个活动之间的交互和数据传递

Android实验报告—数据库接口

数据库接口实验 实验目的: 本实验的目的是使学生深入了解Android数据存储和访问的方法,利用SQLite进行数据存储及访问。通过实验,掌握DatePicker和TimePicker的使用方法。 实验要求: 设计程序实现一个日期信息记录数据库软件,如下图所示 设计界面,如图所示,利用SQLite实现数据库的建立、数据表中的信息的删改、查等操作。使用DatePicker和TimePicker来动态选择日期和时间,将设置的日期和时间信息写入到数据库中。 程序源码(可付纸)(包括XML和Java文件): mcy.java package cn.mcy; import java.util.Calendar; import android.app.Activity; import android.content.ContentValues; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.view.View;

import android.view.View.OnClickListener; import android.widget.Button; import android.widget.DatePicker; import android.widget.EditText; import android.widget.TextView; import android.widget.TimePicker; import android.widget.Toast; public class mcy extends Activity { /** Called when the activity is first created. */ private EditText edtEntry,edtIDEntry; private Button btnAdd,btnShowAll,btnClearShow,btnDeleteAll,btnIDDelete,btnIDSeach,btnIDRefr esh; private TextView tvSShow; private int mYear,mMonth,mDay,mHour,mMinute; private TimePicker tp; private DatePicker dp; private static final String DB_FILE="students.db",DB_TABLE="students"; private SQLiteDatabase mStuDbRW; @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); mStuDbRW.close(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(https://www.360docs.net/doc/e77574705.html,yout.main); mcy11 friDbHp=new mcy11(getApplicationContext(),DB_FILE,null,1); friDbHp.sCreateTableCommand="CREATE TABLE "+DB_TABLE+"("+"_id INTEGER PRIMARY KEY,"+"id TEXT NOT NULL,"+"date TEXT,"+"time TEXT);"; mStuDbRW=friDbHp.getWritableDatabase(); //生成一个数据库mStuDbRW tvSShow=(TextView) findViewById(https://www.360docs.net/doc/e77574705.html,SShow); edtEntry=(EditText) findViewById(R.id.edtEntry); edtIDEntry=(EditText) findViewById(R.id.edtIDEntry); btnAdd=(Button) findViewById(R.id.btnAdd); btnShowAll=(Button) findViewById(R.id.btnShowAll); btnClearShow=(Button) findViewById(R.id.btnClearShow); btnDeleteAll=(Button) findViewById(R.id.btnDeleteAll); btnIDDelete=(Button) findViewById(R.id.btnIDDelete); btnIDSeach=(Button) findViewById(R.id.btnIDSeach); btnIDRefresh=(Button) findViewById(R.id.btnIDRefresh); tp=(TimePicker) findViewById(R.id.TimePicker01);

Android-Room数据库的使用方法教程

Android-Room数据库的使用方法教程 Room是一个持久性数据库,提供了SQLite的抽象层,以便在充分利用SQLite的同时允许流畅的数据库访问。这篇文章主要介绍了详细介绍Android-Room数据库的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧。 为什么会选择Room? 前面我也说到了现在也有不少开源的数据库给大家使用,那为什么我们还要去学习使用这个库呢?当然不是我前面说的“正不正统”的原因了。 因为Room有下面几个优点: ①SQL查询在编译时就会验证- 在编译时检查每个@Query和@Entity等,这就意味着没有任何运行时错误的风险可能会导致应用程序崩溃(并且它不仅检查语法问题,还会检查是否有该表)

②较少的模板代码 ③与LiveData 集成 该如何使用它? 1、在app/build.gradle中添加以下依赖 implementation 'android.arch.persistence.room:runtime:1.0.0' annotationProcessor 'android.arch.persistence.room:compiler:1.0.0' 你可以点击这里查看最新依赖版本号 2、创建JavaBean @Entity public class User {

@PrimaryKey(autoGenerate = true)//主键是否自动增长,默认为false private int id; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; }

android的网络管理设计与实现

android的网络管理设计与实现

目录 摘要................................................................... - 3 - ABSTRACT........................................................... - 5 - 绪论................................................................... - 6 - 1 Android的架构分析.................................... - 7 - 1.1 Android的功能特征........................ - 7 - 1.2 Android架构分析............................ - 7 - 1.2.1应用程序框架........................ - 8 - 1.2.2类库........................................ - 8 - 1.2.3 Android运行时组件.......... - 10 - 1.3 Android应用的构成和工作机制.. - 10 - 2 手机网络管理平台前台设计实现............. - 11 - 2.1 系统设计需求................................. - 11 - 2.1.1 需求分析............................. - 11 - 2.1.2 功能模块............................. - 12 - 2.1.3 数据库设计......................... - 13 - 2.1.4 性能及安全性分析............. - 15 - 2.2 系统代码实现................................. - 15 - 2.2.1 Package Explorer中的组件- 15 - 2.2.2应用程序的资源.................. - 16 - 2.2.3 布局文件main.xml............ - 16 - 2.3 软件测试实现............................... - 17 -

数据库课程设计题目16个经典实例学习资料.doc

数据库课程设计题目16个经典实例 1.机票预定信息系统 系统功能的基本要求: 航班基本信息的录入,包括航班的编号、飞机名称、机舱等级等。机票信息,包括票价、折扣、当前预售状态及经手业务员等。客户基本信息,包括姓名、联系方式、证件及号码、付款情况等。按照一定条件查询、统计符合条件的航班、机票等;对结果打印输出。 2.长途汽车信息管理系统 系统功能的基本要求: 线路信息,包括出发地、目的地、出发时间、所需时间等。汽车信息:包括汽车的种类及相应的票价、最大载客量等。票价信息:包括售票情况、查询、打印相应的信息。 3.人事信息管理系统 系统功能基本要求: 员工各种信息:包括员工的基本信息,如编号、姓名、性别、学历、所属部门、毕业院校、健康情况、职称、职务、奖惩等;员工各种信息的修改;对转出、辞退、退休员工信息的删除;按照一定条件,查询、统计符合条件的员工信息;教师教学信息的录入:教师编号、姓名、课程编号、课程名称、课程时数、学分、课程性质等。科研信息的录入:教师编号、研究方向、课题研究情况、专利、论文及著作发表情况等。按条件查询、统计,结果打印输出。 4.超市会员管理系统 系统功能的基本要求: 加入会员的基本信息,包括:成为会员的基本条件、优惠政策、优惠时间等。会员的基本信息,包括姓名、性别、年龄、工作单位、联系方式等。会员购物信息:购买物品编号、物品名称、所属种类,数量,价格等。会员返利信息,包括会员积分的情况,享受优惠的等级等。对货物流量及消费人群进行统计输出。 5.客房管理系统 系统功能的基本要求: 客房各种信息,包括客房的类别、当前的状态、负责人等;客房信息的查询和修改,包括按房间号查询住宿情况、按客户信息查询房间状态等。以及退房、订房、换房等信息的修改。对查询、统计结果打印输出。 6.药品存销信息管理系统 系统功能基本要求 药品信息,包括药品编号、药品名称、生产厂家、生产日期、保质期、用途、价格、数量、经手人等;员工信息,包括员工编号、姓名、性别、年龄、学历、职务等;客户信息,包括客户编号、姓名、联系方式、购买时间、购买药品编号、名称、数量等。入库和出库信息,包括当前库存信息、药品存放位置、入库数量和出库数量的统计。

Android客户端与服务器数据交互流程

Android客户端与服务器数据交互流程 一个门户网站的制作的流程:首先,由网页设计师只做网页设计,即画出来网站在浏览器中显示的样子,然后由前端人员编写 Html+CSS+JS来实现网站的动态效果,比如说导航栏的下拉显示,然后Ajax的局部信息更新等,然后通过后台程序如JSP,PHP, .NET等语言将数据库中的信息与前台页面相结合,这样,一个站就这样被建好了。而Android客户端,也是有UI设计师,UI前端,程序构成的,同样程序这边的话,最近Html5+CSS3的火热开启,很多公司也需要html5+css3进行Android程序的开发了。呜呜,抢我的饭碗。虽然说哥也是懂html+css的。嘿嘿,这样解释的话,可能大家不清楚,其实木有必要弄清楚网站的建站过程,这里只是给大家普及一下知识,没必要弄清楚。 基础知识:我们需要知道,Http协议是基于TCP协议的,而TCP协议是一种有连接,可靠的传输协议,如果丢失的话,会重传。所以这样的话,就不会有数据的丢失了。而Http协议有三种方法,Get,Post,Head 方法,但是用的多的只有Get和Post方法,Get方法是将请求参数放在请求头中,所以请求的参数在URL中可见,而Post方法是将请求参数放在数据部分,所以在URL中不可见,Post相对来说保密,所以在提交重要信息的时候,用的都是HttpPost方法来实现的. 而在B/S模式中,B代表浏览器,S代表服务器,在浏览器和服务器的通信之中,因为B/S之间不会一直保持连接,所以才会加入Cookie 机制,来辨认所操作的对象。用户浏览网页的操作如下:当用户点击

一个连接或者一个按钮的时候,浏览器通过发送一个请求给服务器,然后由服务器接收该请求,然后解析到用户请求的是哪些内容,然后查找到相关资源,再将数据返回给浏览器,由浏览器解析数据,然后显示给用户看到用户所需要看到的页面。所以,Android和B/S模式差不多,其实也就是发送请求,接收数据,然后解析数据,显示到手机上的过程,没什么太大的区别,谁让咱用的是互联网,用的是TCP/IP 协议呢,是吧。要理解是:所有的操作都是向服务器请求数据的过程。 hp文件,然后浏览器会将php文件解析成为html然后显示在浏览器上显示。

相关文档
最新文档